From 139a4858b199b32831f204fa31be3c9fa448ad52 Mon Sep 17 00:00:00 2001 From: jackdewinter Date: Tue, 16 Jan 2024 16:40:45 -0800 Subject: [PATCH] Issue 901 (#949) * https://github.com/jackdewinter/pymarkdown/issues/827 --- changelog.md | 15 +- docs/developer.md | 70 +- docs/rules.md | 47 +- docs/rules/rule_md009.md | 2 + docs/rules/rule_md030.md | 10 + publish/coverage.json | 8 +- publish/pylint_suppression.json | 12 +- publish/test-results.json | 86 +- pymarkdown/file_scan_helper.py | 237 +- pymarkdown/plugin_manager/found_plugin.py | 1 + pymarkdown/plugin_manager/plugin_details.py | 1 + pymarkdown/plugin_manager/plugin_manager.py | 84 +- .../plugin_manager/plugin_scan_context.py | 8 +- pymarkdown/plugins/rule_md_005.py | 1 + pymarkdown/plugins/rule_md_009.py | 1 + pymarkdown/plugins/rule_md_010.py | 1 + pymarkdown/plugins/rule_md_027.py | 185 +- pymarkdown/plugins/rule_md_030.py | 63 +- pymarkdown/plugins/rule_md_038.py | 16 +- pymarkdown/plugins/rule_md_047.py | 1 + .../tokens/block_quote_markdown_token.py | 12 +- .../plugins/bad/bad_fix_token_unsupported.py | 1 + .../plugins/bad/bad_next_line_fix.py | 3 +- .../plugins/bad/bad_update_last_line.py | 1 + .../good_block_quote_empty_just_blank.md | 2 +- ...ood_block_quote_indent_with_blank_space.md | 2 +- test/rules/test_md001.py | 648 +-- test/rules/test_md004.py | 1384 ++---- test/rules/test_md005.py | 3266 +++----------- test/rules/test_md006.py | 1020 +---- test/rules/test_md007.py | 2503 ++--------- test/rules/test_md009.py | 1208 ++---- test/rules/test_md009_config.py | 151 - test/rules/test_md009_good.py | 514 --- test/rules/test_md010.py | 894 ++-- test/rules/test_md010_block_quote.py | 175 - test/rules/test_md010_ordered_list.py | 427 -- test/rules/test_md010_unordered_list.py | 427 -- test/rules/test_md019.py | 452 +- test/rules/test_md020.py | 4 +- test/rules/test_md021.py | 510 +-- test/rules/test_md023.py | 1092 ++--- test/rules/test_md027.py | 3837 +++-------------- test/rules/test_md027_inline.py | 1882 ++------ test/rules/test_md027_leaf.py | 2011 ++------- test/rules/test_md027_leaf_plus_one.py | 1759 ++------ test/rules/test_md029.py | 2557 +++-------- test/rules/test_md030_ordered.py | 1618 ++----- test/rules/test_md030_unordered.py | 1743 ++------ test/rules/test_md035.py | 1151 +---- test/rules/test_md037.py | 924 +--- test/rules/test_md038.py | 498 +-- test/rules/test_md039.py | 1292 +----- test/rules/test_md047.py | 448 +- test/rules/test_md048.py | 668 +-- test/rules/test_plugin_manager.py | 321 +- test/rules/utils.py | 210 + .../tokens/test_block_quote_markdown_token.py | 23 + test/utils.py | 2 +- 59 files changed, 7788 insertions(+), 28701 deletions(-) delete mode 100644 test/rules/test_md009_config.py delete mode 100644 test/rules/test_md009_good.py delete mode 100644 test/rules/test_md010_block_quote.py delete mode 100644 test/rules/test_md010_ordered_list.py delete mode 100644 test/rules/test_md010_unordered_list.py create mode 100644 test/rules/utils.py create mode 100644 test/tokens/test_block_quote_markdown_token.py diff --git a/changelog.md b/changelog.md index 600d8c07e..e8d642c03 100644 --- a/changelog.md +++ b/changelog.md @@ -3,7 +3,9 @@ ## Unversioned - In Main, Not Released This release is going to focus on getting the feature list complete -for a version 1.0 release in early 2024. +for a version 1.0 release in early 2024. To a large extent, this +involves adding the "fix" feature for some rules, and double checking +the output of many of the existing rules, looking for missing issues. ### Added @@ -46,8 +48,12 @@ for a version 1.0 release in early 2024. ### Changed +- [Issue 806](https://github.com/jackdewinter/pymarkdown/issues/806) + - Documentation updated to denote fixes. - [Issue 812](https://github.com/jackdewinter/pymarkdown/issues/812) - Rule MD014 - Changed documentation to describe why not autofix +- [Issue 827](https://github.com/jackdewinter/pymarkdown/issues/827) + - Finished research on which rules are fixable and sorted. - [Issue 901](https://github.com/jackdewinter/pymarkdown/issues/901) - noticed cases where `len(x)` was being used instead of `x` or `not x` - [Issue 913](https://github.com/jackdewinter/pymarkdown/issues/913) @@ -66,6 +72,13 @@ for a version 1.0 release in early 2024. - None +### Completed + +- [Issue 827](https://github.com/jackdewinter/pymarkdown/issues/827) + - researched annotated each rule + - rules "in queue" have no annotation yet, ones that have fixes have docs + updated, ones that are not eligible have reason why + ## Version 0.9.15 - Date: 2023-12-05 This release is mainly to fix issues related to technical debt. The PyMarkdown diff --git a/docs/developer.md b/docs/developer.md index 3ae083a7a..1e70cf7d4 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -138,6 +138,73 @@ report_next_line_error completed_file +## Fix Conflict Checks + +MD001 & md003 - Md003 is not fixable +MD004 & md006 - `mix_md004_md006` - duplicate of inverse - disabled by default + & md007 - `mix_md004_md007` - check + & md032 - `mix_md004_md032` - future +MD005 & md007 `mix_md005_md007` + & md023 - from below + & md027 - `mix_md005_md007` + & md029 - `mix_md005_md029` + & md030 - `mix_md005_md030` + & md033 - safe +MD007 & md004 - `mix_md007_md004` + & md005 - `mix_md007_md005` + & md027 - `mix_md007_md027` + & md030 - `mix_md007_md030` +md009 & md012 - future + & md023 - `mix_md009_md023` - check -> 009, 0027, 023 + & md027 - `mix_md009_md027` - duplicate of inverse + & md033 - future +MD010 & md019 - `mix_md010_md019` - duplicate of inverse + & md021 - `mix_md010_md021` - duplicate of inverse + & md022 - safe + & md030 - `mix_md010_md030` + & md031 - safe + & md040 - safe + & md047 - `mix_md010_md047` +MD019 & md010 - `mix_md019_md010` - duplicate of inverse + & md023 - `mix_md019_md023` - check + & md047 - `mix_md019_md047` - double check, not required +MD021 & md010 - `mix_md021_md010` - check +MD023 & md005 - up + & md009 - `mix_md023_md009` - duplicate of inverse + & md019 - `mix_md023_md019` - duplicate of inverse + & md022 - safe + & md027 - `mix_md023_md027` + & md030 - `mix_md023_md030` + & md032 - safe +MD027 & md003 - safe + & md005 - `mix_md027_md005` + & md007 - `mix_md027_md007` - check + & md009 - `mix_md027_md009` + & md012 - safe + & md013 - safe + & md022 - safe + & md023 - `mix_md027_md023` + & md028 - safe + & md030 - `mix_md027_md030` + & md031 - safe + & md032 - safe +MD029 & md030 - `mix_md029_md005` +MD030 & md005 - `mix_md030_md005` + & md007 - `mix_md030_md007` - check + & md010 - `mix_md030_md010` + & md027 - `mix_md030_md027` + & md030 - `mix_md030_md023` +MD035 - none +MD037 - none +MD039 - none +MD047 & md010 - `mix_md047_md010` - double check + & md019 - `mix_md047_md019` - double check +MD048 - none + +MD006 & md004 - `mix_md006_md004` up (disabled by default) + md007 (disabled by default) + md027 (disabled by default) + possible -> MD005, Md007 possible -> MD019/MD021, MD023 possible -> md027 19/21/23/05/07 when blanks inside of list @@ -158,6 +225,7 @@ MD019 AtxHeadingMarkdownToken extracted_whitespace MD021 AtxHeadingMarkdownToken extracted_whitespace, extra_end_data MD023 AtxHeadingMarkdownToken extracted_whitespace MD029 OrderedListStartMarkdownToken list_start_content +md030 spaces after list markers, def = 1 MD035 ThematicBreakMarkdownToken start_character,rest_of_line MD037 TextMarkdownToken (within emphasis) token_text MD038 InlineCodeSpanMarkdownToken span_text @@ -177,5 +245,3 @@ MD027 BlankLineMarkdownToken extracted_whitespace NewListItemMarkdownToken indent_level, extracted_whitespace UnorderedListStartMarkdownToken indent_level, extracted_whitespace, column_number, leading_spaces OrderedListStartMarkdownToken indent_level, extracted_whitespace, column_number, leading_spaces - -md030 spaces after list markers, def = 1 diff --git a/docs/rules.md b/docs/rules.md index eaaa793a2..934773895 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -1,4 +1,49 @@ -# Implemented Rules +# Plugin Rules + +Plugins are the manner in which rules are included into PyMarkdown. While there +are a healthy set of rules shipped with PyMarkdown, there is also support for any +user to provide their own plugins. + +Each shipped plugins comes completed with its own documentation. This documentation +follows this format. + +- Title and High Level Information + - The name of the rule, any aliases for the rule, and whether the autofix option + is available for this rule. +- Deprecation + - If this plugin is deprecated in favor of another plugin, what that other plugin + is. +- Summary + - A quick one line summary of what the rule does. +- Reasoning + - Why this rule was implemented. + - Readability, Consistency, Simplicity, Correctness, Portability +- Examples + - Both positive and negative examples to illustrate the rule. Since the rule + triggers on negative examples, the negative examples are usually first, often + with the corrected positive for of the examples following them. +- Configuration + - Two tables to present that configuration, even if the only configuration is + the `enabled` value. The first table shows acceptable prefixes for any configuration + value and the second table lists the value's name, its type, its default value, + and a simple description of the configuration. +- Origination of Rule + - A compliment to the `Reasoning` section, this section talks about the history + of the rule. +- Fix Description + - If autofix is available for the rule, what the effects of using autofix are. + - If autofix is not available for the rule, why the decision to not autofix was + made. + - If this section is not present, it means that the rule is currently in queue + for adding autofix support. + +A big note on the Fix Description for any plugin that does not support autofix. +That section contains the reasons why the decision was made at the time. Given +extra conversation and a solid, predictable algorithm to apply, it is possible to +change that decision. If you believe that you have a solution, please file an +issue and present your case to our team! + +## Implemented Rules These are the rules that are currently implemented. diff --git a/docs/rules/rule_md009.md b/docs/rules/rule_md009.md index 499af2a61..b02f2b921 100644 --- a/docs/rules/rule_md009.md +++ b/docs/rules/rule_md009.md @@ -15,6 +15,8 @@ Trailing spaces. ## Reasoning +### Simplicity + The primary reason for enabling this rule is simplicity. Two spaces at the end of a line within a paragraph produces a Hard Line Break element. Other than that, there is no other reason for trailing spaces on any line diff --git a/docs/rules/rule_md030.md b/docs/rules/rule_md030.md index cd7bcead7..913356018 100644 --- a/docs/rules/rule_md030.md +++ b/docs/rules/rule_md030.md @@ -5,6 +5,10 @@ | `md030` | | `list-marker-space` | +| Autofix Available | +| --- | +| Yes | + ## Summary Spaces after list markers. @@ -81,3 +85,9 @@ to trigger this rule: This rule is largely inspired by the MarkdownLint rule [MD030](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md030---spaces-after-list-markers). + +## Fix Description + +When fixed, the number of spaces between a list start and the following text are +set to the configured spacing. By default, this means ordered and unordered list +start sequences will be set to have 1 space before the text. diff --git a/publish/coverage.json b/publish/coverage.json index cf11b4c33..d3777fcfa 100644 --- a/publish/coverage.json +++ b/publish/coverage.json @@ -2,12 +2,12 @@ "projectName": "pymarkdown", "reportSource": "pytest", "branchLevel": { - "totalMeasured": 4699, - "totalCovered": 4699 + "totalMeasured": 4761, + "totalCovered": 4761 }, "lineLevel": { - "totalMeasured": 19151, - "totalCovered": 19151 + "totalMeasured": 19275, + "totalCovered": 19275 } } diff --git a/publish/pylint_suppression.json b/publish/pylint_suppression.json index 095d4e8f2..841bb93d1 100644 --- a/publish/pylint_suppression.json +++ b/publish/pylint_suppression.json @@ -94,7 +94,8 @@ "protected-access": 1 }, "pymarkdown/file_scan_helper.py": { - "too-many-arguments": 5 + "too-many-arguments": 8, + "too-many-locals": 4 }, "pymarkdown/general/__init__.py": {}, "pymarkdown/general/bad_tokenization_error.py": {}, @@ -255,7 +256,8 @@ }, "pymarkdown/plugin_manager/plugin_manager.py": { "too-many-instance-attributes": 1, - "too-many-arguments": 3 + "too-many-arguments": 4, + "too-many-locals": 1 }, "pymarkdown/plugin_manager/plugin_modify_context.py": { "deprecated-decorator": 2 @@ -305,7 +307,7 @@ "pymarkdown/plugins/rule_md_026.py": {}, "pymarkdown/plugins/rule_md_027.py": { "too-many-instance-attributes": 1, - "too-many-arguments": 4 + "too-many-arguments": 6 }, "pymarkdown/plugins/rule_md_028.py": {}, "pymarkdown/plugins/rule_md_029.py": {}, @@ -491,8 +493,8 @@ "too-many-instance-attributes": 24, "too-many-public-methods": 4, "too-few-public-methods": 39, - "too-many-arguments": 220, - "too-many-locals": 33, + "too-many-arguments": 226, + "too-many-locals": 38, "chained-comparison": 1, "too-many-boolean-expressions": 2, "protected-access": 26, diff --git a/publish/test-results.json b/publish/test-results.json index b76dafd0b..f17dc205b 100644 --- a/publish/test-results.json +++ b/publish/test-results.json @@ -1108,7 +1108,7 @@ }, { "name": "test.rules.test_md001", - "totalTests": 15, + "totalTests": 14, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1132,7 +1132,7 @@ }, { "name": "test.rules.test_md004", - "totalTests": 29, + "totalTests": 35, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1140,7 +1140,7 @@ }, { "name": "test.rules.test_md005", - "totalTests": 65, + "totalTests": 88, "failedTests": 0, "errorTests": 0, "skippedTests": 2, @@ -1148,7 +1148,7 @@ }, { "name": "test.rules.test_md006", - "totalTests": 22, + "totalTests": 24, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1156,7 +1156,7 @@ }, { "name": "test.rules.test_md007", - "totalTests": 54, + "totalTests": 62, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1164,23 +1164,7 @@ }, { "name": "test.rules.test_md009", - "totalTests": 20, - "failedTests": 0, - "errorTests": 0, - "skippedTests": 0, - "elapsedTimeInMilliseconds": 0 - }, - { - "name": "test.rules.test_md009_config", - "totalTests": 4, - "failedTests": 0, - "errorTests": 0, - "skippedTests": 0, - "elapsedTimeInMilliseconds": 0 - }, - { - "name": "test.rules.test_md009_good", - "totalTests": 14, + "totalTests": 36, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1188,31 +1172,7 @@ }, { "name": "test.rules.test_md010", - "totalTests": 9, - "failedTests": 0, - "errorTests": 0, - "skippedTests": 0, - "elapsedTimeInMilliseconds": 0 - }, - { - "name": "test.rules.test_md010_block_quote", - "totalTests": 4, - "failedTests": 0, - "errorTests": 0, - "skippedTests": 0, - "elapsedTimeInMilliseconds": 0 - }, - { - "name": "test.rules.test_md010_ordered_list", - "totalTests": 10, - "failedTests": 0, - "errorTests": 0, - "skippedTests": 0, - "elapsedTimeInMilliseconds": 0 - }, - { - "name": "test.rules.test_md010_unordered_list", - "totalTests": 10, + "totalTests": 49, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1260,7 +1220,7 @@ }, { "name": "test.rules.test_md019", - "totalTests": 9, + "totalTests": 15, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1276,7 +1236,7 @@ }, { "name": "test.rules.test_md021", - "totalTests": 11, + "totalTests": 16, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1292,7 +1252,7 @@ }, { "name": "test.rules.test_md023", - "totalTests": 23, + "totalTests": 31, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1324,7 +1284,7 @@ }, { "name": "test.rules.test_md027", - "totalTests": 88, + "totalTests": 104, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1332,7 +1292,7 @@ }, { "name": "test.rules.test_md027_inline", - "totalTests": 44, + "totalTests": 47, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1340,7 +1300,7 @@ }, { "name": "test.rules.test_md027_leaf", - "totalTests": 48, + "totalTests": 49, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1364,7 +1324,7 @@ }, { "name": "test.rules.test_md029", - "totalTests": 55, + "totalTests": 66, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1380,7 +1340,7 @@ }, { "name": "test.rules.test_md030_unordered", - "totalTests": 33, + "totalTests": 46, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1420,7 +1380,7 @@ }, { "name": "test.rules.test_md035", - "totalTests": 27, + "totalTests": 28, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1436,7 +1396,7 @@ }, { "name": "test.rules.test_md037", - "totalTests": 21, + "totalTests": 23, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1516,7 +1476,7 @@ }, { "name": "test.rules.test_md047", - "totalTests": 9, + "totalTests": 13, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1524,7 +1484,7 @@ }, { "name": "test.rules.test_md048", - "totalTests": 14, + "totalTests": 16, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1658,6 +1618,14 @@ "skippedTests": 0, "elapsedTimeInMilliseconds": 0 }, + { + "name": "test.tokens.test_block_quote_markdown_token", + "totalTests": 1, + "failedTests": 0, + "errorTests": 0, + "skippedTests": 0, + "elapsedTimeInMilliseconds": 0 + }, { "name": "test.tokens.test_end_token", "totalTests": 1, diff --git a/pymarkdown/file_scan_helper.py b/pymarkdown/file_scan_helper.py index 80e49c55a..88e676dfc 100644 --- a/pymarkdown/file_scan_helper.py +++ b/pymarkdown/file_scan_helper.py @@ -10,7 +10,7 @@ import shutil import sys import tempfile -from typing import Callable, Dict, List, Optional, Tuple, Union, cast +from typing import Callable, Dict, List, Optional, Set, Tuple, Union, cast from pymarkdown.application_file_scanner import ApplicationFileScanner from pymarkdown.extensions.pragma_token import PragmaToken @@ -22,6 +22,7 @@ from pymarkdown.plugin_manager.bad_plugin_fix_error import BadPluginFixError from pymarkdown.plugin_manager.fix_line_record import FixLineRecord from pymarkdown.plugin_manager.fix_token_record import FixTokenRecord +from pymarkdown.plugin_manager.found_plugin import FoundPlugin from pymarkdown.plugin_manager.plugin_manager import PluginManager from pymarkdown.plugin_manager.plugin_scan_context import PluginScanContext from pymarkdown.return_code_helper import ApplicationResult, ReturnCodeHelper @@ -142,9 +143,7 @@ def __scan_file( """ POGGER.info("Scanning file '$'.", next_file_name) - context = self.__plugins.starting_new_file( - next_file_name, False, None, fix_token_map=None - ) + context = self.__plugins.starting_new_file(next_file_name) try: POGGER.info("Starting file '$'.", next_file_name) @@ -267,20 +266,25 @@ def __process_file_fix_rescan( ParserLogger.sync_on_next_call() return actual_tokens - # pylint: disable=too-many-arguments - def __process_file_fix( + # pylint: disable=too-many-arguments, too-many-locals + def __process_file_fix_pass( self, next_file: str, next_file_name: str, fix_debug: bool, fix_file_debug: bool, fix_nolog_rescan: bool, - ) -> bool: - # TODO add more protections around fixing i.e. IOError handling - + fix_list: List[str], + collect_list: List[str], + ) -> Tuple[bool, Set[str], Set[str]]: # Scan the provided file for any token fixes. - next_file_two, actual_tokens, fix_token_map = self.__process_file_fix_tokens( - next_file, next_file_name, fix_debug, fix_file_debug + ( + next_file_two, + actual_tokens, + fix_token_map, + collected_token_triggers, + ) = self.__process_file_fix_tokens( + next_file, next_file_name, fix_debug, fix_file_debug, fix_list, collect_list ) did_any_tokens_get_fixed = bool(fix_token_map) @@ -302,8 +306,15 @@ def __process_file_fix( ( this_file_fix_line_records, temporary_line_file_name, + collected_line_triggers, ) = self.__process_file_fix_lines( - next_file_two, next_file_name, actual_tokens, fix_debug, fix_file_debug + next_file_two, + next_file_name, + actual_tokens, + fix_debug, + fix_file_debug, + fix_list, + collect_list, ) # If anything was fixed, copy the temporary file on top of the original file @@ -321,11 +332,127 @@ def __process_file_fix( if fix_debug and fix_file_debug: print(f"Remove:{next_file_two}") os.remove(next_file_two) + + return did_anything_get_fixed, collected_token_triggers, collected_line_triggers + + # pylint: enable=too-many-arguments, too-many-locals + + # pylint: disable=too-many-arguments, too-many-locals + def __process_file_fix_next_level( + self, + plugins_by_fix_level: Dict[int, List[str]], + minimum_fix_level: int, + fixes_by_id: Dict[str, FoundPlugin], + next_file: str, + next_file_name: str, + fix_debug: bool, + fix_file_debug: bool, + fix_nolog_rescan: bool, + ) -> Tuple[bool, bool, int]: + keep_processing = False + collect_list = [] + for fix_level, level_list in plugins_by_fix_level.items(): + if fix_level == minimum_fix_level: + fix_list = level_list[:] + elif fix_level > minimum_fix_level: + collect_list.extend(level_list) + + ( + did_anything_get_fixed_this_time, + collected_token_triggers, + collected_line_triggers, + ) = self.__process_file_fix_pass( + next_file, + next_file_name, + fix_debug, + fix_file_debug, + fix_nolog_rescan, + fix_list, + collect_list, + ) + + trigger_set = collected_token_triggers | collected_line_triggers + new_minimum_fix_level: Optional[int] = None + for next_triggered_plugin_id in trigger_set: + triggered_plugin_fix_level = fixes_by_id[ + next_triggered_plugin_id + ].plugin_fix_level + assert triggered_plugin_fix_level > minimum_fix_level + if new_minimum_fix_level is None: + new_minimum_fix_level = triggered_plugin_fix_level + else: + new_minimum_fix_level = min( + new_minimum_fix_level, triggered_plugin_fix_level + ) + if new_minimum_fix_level is not None: + keep_processing = True + minimum_fix_level = new_minimum_fix_level + + return keep_processing, did_anything_get_fixed_this_time, minimum_fix_level + + # pylint: enable=too-many-arguments, too-many-locals + + # pylint: disable=too-many-arguments, too-many-locals + def __process_file_fix( + self, + next_file: str, + next_file_name: str, + fix_debug: bool, + fix_file_debug: bool, + fix_nolog_rescan: bool, + ) -> bool: + enabled_plugins_with_fixes = filter( + lambda x: x.plugin_supports_fix, self.__plugins.enabled_plugins + ) + fixes_by_id: Dict[str, FoundPlugin] = { + i.plugin_id.lower(): i for i in enabled_plugins_with_fixes + } + + enabled_plugins_with_fixes = filter( + lambda x: x.plugin_supports_fix, self.__plugins.enabled_plugins + ) + fix_plugins_with_levels = [ + (i.plugin_id, i.plugin_fix_level) for i in enabled_plugins_with_fixes + ] + + plugins_by_fix_level: Dict[int, List[str]] = {} + for next_pair in fix_plugins_with_levels: + pair_plugin_id = next_pair[0] + pair_fix_level = next_pair[1] + if pair_fix_level in plugins_by_fix_level: + level_list = plugins_by_fix_level[pair_fix_level] + else: + level_list = [] + plugins_by_fix_level[pair_fix_level] = level_list + level_list.append(pair_plugin_id) + minimum_fix_level = min(plugins_by_fix_level.keys()) + did_anything_get_fixed = False + keep_processing = True + + while keep_processing: + ( + keep_processing, + did_anything_get_fixed_this_time, + minimum_fix_level, + ) = self.__process_file_fix_next_level( + plugins_by_fix_level, + minimum_fix_level, + fixes_by_id, + next_file, + next_file_name, + fix_debug, + fix_file_debug, + fix_nolog_rescan, + ) + did_anything_get_fixed = ( + did_anything_get_fixed or did_anything_get_fixed_this_time + ) + return did_anything_get_fixed - # pylint: enable=too-many-arguments + # pylint: enable=too-many-arguments, too-many-locals - # pylint: disable=too-many-arguments + # pylint: disable=too-many-arguments, too-many-locals def __process_file_fix_lines( self, next_file: str, @@ -333,18 +460,28 @@ def __process_file_fix_lines( actual_tokens: List[MarkdownToken], fix_debug: bool, fix_file_debug: bool, - ) -> Tuple[List[FixLineRecord], str]: + fix_list: List[str], + collect_list: List[str], + ) -> Tuple[List[FixLineRecord], str, Set[str]]: source_provider = FileSourceProvider(next_file) with tempfile.NamedTemporaryFile() as temp_output: temporary_file_name = temp_output.name with open(temporary_file_name, "wt", encoding="utf-8") as source_file: POGGER.info("Scanning before line-by-line fixes.") - context = self.__plugins.starting_new_file( + fix_context = self.__plugins.starting_new_file( next_file_name, fix_mode=True, temp_output=source_file, fix_token_map=None, ) + report_context = self.__plugins.starting_new_file( + next_file_name, constraint_id_list=collect_list + ) + context_map: Dict[str, PluginScanContext] = { + i: fix_context for i in fix_list + } + for i in collect_list: + context_map[i] = report_context # Due to context required to process the line requirements, we need go # through all the tokens first, before processing the lines. @@ -354,23 +491,38 @@ def __process_file_fix_lines( # picture of the tokens. for next_token in actual_tokens: POGGER.info("Processing tokens: $", next_token) - self.__plugins.next_token(context, next_token) + self.__plugins.next_token(fix_context, next_token, context_map) POGGER.info("Completed token scanning.") - self.__process_lines_in_file(source_provider, context, next_file_name) - this_file_fix_line_records = context.fix_line_records + self.__process_lines_in_file( + source_provider, fix_context, next_file_name, context_map + ) + this_file_fix_line_records = fix_context.fix_line_records if this_file_fix_line_records and fix_debug: - for next_record in context.fix_line_records: + for next_record in fix_context.fix_line_records: print(next_record) self.__print_file_in_debug_mode(fix_debug, fix_file_debug, temporary_file_name) - return this_file_fix_line_records, temporary_file_name + return ( + this_file_fix_line_records, + temporary_file_name, + report_context.get_triggered_rules(), + ) - # pylint: enable=too-many-arguments + # pylint: enable=too-many-arguments, too-many-locals + # pylint: disable=too-many-arguments def __process_file_fix_tokens( - self, next_file: str, next_file_name: str, fix_debug: bool, fix_file_debug: bool - ) -> Tuple[str, List[MarkdownToken], Dict[MarkdownToken, List[FixTokenRecord]]]: + self, + next_file: str, + next_file_name: str, + fix_debug: bool, + fix_file_debug: bool, + fix_list: List[str], + collect_list: List[str], + ) -> Tuple[ + str, List[MarkdownToken], Dict[MarkdownToken, List[FixTokenRecord]], Set[str] + ]: self.__print_file_in_debug_mode(fix_debug, fix_file_debug, next_file) POGGER.info("Scanning file to fix '$' token-by-token.", next_file_name) @@ -381,30 +533,49 @@ def __process_file_fix_tokens( ) fix_token_map: Dict[MarkdownToken, List[FixTokenRecord]] = {} - context = self.__plugins.starting_new_file( - next_file_name, fix_mode=True, temp_output=None, fix_token_map=fix_token_map + fix_context = self.__plugins.starting_new_file( + next_file_name, + fix_mode=True, + temp_output=None, + fix_token_map=fix_token_map, + constraint_id_list=fix_list, + ) + report_context = self.__plugins.starting_new_file( + next_file_name, constraint_id_list=collect_list ) + + context_map = {i: fix_context for i in fix_list} + for i in collect_list: + context_map[i] = report_context + for next_token in actual_tokens: POGGER.info("Processing token: $", next_token) - self.__plugins.next_token(context, next_token) + self.__plugins.next_token(fix_context, next_token, context_map) POGGER.info("Completed scanning file '$' for fixes.", next_file_name) - self.__plugins.completed_file(context, -1) + self.__plugins.completed_file(fix_context, -1, context_map) - if context.get_fix_token_map(): + if fix_context.get_fix_token_map(): ( next_file, actual_tokens, fix_token_map, ) = self.__process_file_fix_tokens_apply_fixes( - context, + fix_context, next_file, actual_tokens, fix_token_map, fix_debug, fix_file_debug, ) - return next_file, actual_tokens, fix_token_map + return ( + next_file, + actual_tokens, + fix_token_map, + report_context.get_triggered_rules(), + ) + + # pylint: enable=too-many-arguments # pylint: disable=too-many-arguments def __process_file_fix_tokens_apply_fixes( @@ -526,6 +697,7 @@ def __process_lines_in_file( source_provider: FileSourceProvider, context: PluginScanContext, next_file_name: str, + context_map: Optional[Dict[str, PluginScanContext]] = None, ) -> None: line_number, next_line = 1, source_provider.get_next_line() while next_line is not None: @@ -536,12 +708,13 @@ def __process_lines_in_file( next_line, source_provider.is_at_end_of_file, source_provider.did_final_line_end_with_newline, + context_map, ) line_number += 1 next_line = source_provider.get_next_line() POGGER.info("Completed scanning lines in file '$'.", next_file_name) - self.__plugins.completed_file(context, line_number) + self.__plugins.completed_file(context, line_number, context_map) @staticmethod def is_scan_stdin_specified(args: argparse.Namespace) -> bool: diff --git a/pymarkdown/plugin_manager/found_plugin.py b/pymarkdown/plugin_manager/found_plugin.py index 7bd730387..4cbf49154 100644 --- a/pymarkdown/plugin_manager/found_plugin.py +++ b/pymarkdown/plugin_manager/found_plugin.py @@ -29,6 +29,7 @@ class FoundPlugin: plugin_url: Optional[str] plugin_configuration: Optional[str] plugin_supports_fix: bool + plugin_fix_level: int plugin_identifiers: List[str] diff --git a/pymarkdown/plugin_manager/plugin_details.py b/pymarkdown/plugin_manager/plugin_details.py index 6b8f1b782..d724c9aa3 100644 --- a/pymarkdown/plugin_manager/plugin_details.py +++ b/pymarkdown/plugin_manager/plugin_details.py @@ -34,3 +34,4 @@ class PluginDetailsV2(PluginDetails): plugin_supports_fix: bool = False plugin_interface_version: int = 2 + plugin_fix_level: int = 1 diff --git a/pymarkdown/plugin_manager/plugin_manager.py b/pymarkdown/plugin_manager/plugin_manager.py index 430f45767..1a1cd12cc 100644 --- a/pymarkdown/plugin_manager/plugin_manager.py +++ b/pymarkdown/plugin_manager/plugin_manager.py @@ -230,6 +230,7 @@ def __handle_argparse_subparser_list( "enabled\n(default)", "enabled\n(current)", "version", + "fix", ] self.__print_columnar_data(headers, show_rows) return ApplicationResult.SUCCESS @@ -261,6 +262,7 @@ def __show_row_if_matches( str(next_plugin.plugin_enabled_by_default), str(is_enabled_now), next_plugin.plugin_version, + "Yes" if next_plugin.plugin_supports_fix else "No", ] show_rows.append(display_row) @@ -382,6 +384,13 @@ def compile_pragmas(self, scan_file: str, pragma_lines: Dict[int, str]) -> None: self.log_pragma_failure, ) + @property + def enabled_plugins(self) -> List[FoundPlugin]: + """ + Get a list of the plugins that are currently enabled. + """ + return self.__enabled_plugins + @classmethod def __find_eligible_plugins_in_directory( cls, directory_to_search: str @@ -577,6 +586,7 @@ def __get_plugin_details( plugin_configuration, plugin_names, plugin_supports_fix, + plugin_fix_level, ) = self.__unpack_plugin_details(plugin_instance) self.__verify_string_field(plugin_instance, "plugin_id", plugin_id) @@ -597,6 +607,10 @@ def __get_plugin_details( self.__verify_string_field( plugin_instance, "plugin_configuration", plugin_configuration ) + if plugin_supports_fix: + self.__verify_integer_field( + plugin_instance, "plugin_fix_level", plugin_fix_level + ) plugin_object = FoundPlugin( plugin_id, @@ -610,6 +624,7 @@ def __get_plugin_details( plugin_url, plugin_configuration, plugin_supports_fix, + plugin_fix_level, [plugin_id, *plugin_names], ) @@ -621,14 +636,26 @@ def __get_plugin_details( return plugin_object + # pylint: disable=too-many-locals def __unpack_plugin_details( self, plugin_instance: RulePlugin ) -> Tuple[ - str, str, str, bool, str, int, Optional[str], Optional[str], List[str], bool + str, + str, + str, + bool, + str, + int, + Optional[str], + Optional[str], + List[str], + bool, + int, ]: try: instance_details = plugin_instance.get_details() plugin_supports_fix = False + plugin_fix_level = -1 ( plugin_id, plugin_name, @@ -653,6 +680,7 @@ def __unpack_plugin_details( and plugin_interface_version == 2 ): plugin_supports_fix = instance_details.plugin_supports_fix + plugin_fix_level = instance_details.plugin_fix_level except Exception as this_exception: raise BadPluginError( class_name=type(plugin_instance).__name__, @@ -676,8 +704,11 @@ def __unpack_plugin_details( plugin_configuration, plugin_names, plugin_supports_fix, + plugin_fix_level, ) + # pylint: enable=too-many-locals + def __register_plugin_id( self, plugin_object: FoundPlugin, instance_file_name: str, next_key: str ) -> None: @@ -866,19 +897,24 @@ def apply_configuration(self, properties: ApplicationProperties) -> None: if next_plugin.plugin_instance.is_starting_new_file_implemented_in_plugin: self.__enabled_plugins_for_starting_new_file.append(next_plugin) + # pylint: disable=too-many-arguments def starting_new_file( self, file_being_started: str, - fix_mode: bool, - temp_output: Optional[TextIOWrapper], - fix_token_map: Optional[Dict[MarkdownToken, List[FixTokenRecord]]], + fix_mode: bool = False, + temp_output: Optional[TextIOWrapper] = None, + fix_token_map: Optional[Dict[MarkdownToken, List[FixTokenRecord]]] = None, + constraint_id_list: Optional[List[str]] = None, ) -> PluginScanContext: """ Inform any listeners that a new current file has been started. """ self.__document_pragmas = {} self.__document_pragma_ranges = [] + for next_plugin in self.__enabled_plugins_for_starting_new_file: + if constraint_id_list and next_plugin.plugin_id not in constraint_id_list: + continue try: next_plugin.plugin_instance.starting_new_file() except Exception as this_exception: @@ -894,6 +930,8 @@ def starting_new_file( context.set_last_line_fixed(None) return context + # pylint: enable=too-many-arguments + def __completed_file_fix_mode_middle( self, context: PluginScanContext, @@ -930,7 +968,12 @@ def __completed_file_fix_mode_end( assert line_append_record is not None context.add_fix_line_record(line_append_record) - def completed_file(self, context: PluginScanContext, line_number: int) -> None: + def completed_file( + self, + context: PluginScanContext, + line_number: int, + context_map: Optional[Dict[str, PluginScanContext]] = None, + ) -> None: """ Inform any listeners that the current file has been completed. """ @@ -942,8 +985,12 @@ def completed_file(self, context: PluginScanContext, line_number: int) -> None: # believes that only one of the paths were covered. # sourcery skip: remove-assert-true for next_plugin in self.__enabled_plugins_for_completed_file: - if context.in_fix_mode and not next_plugin.plugin_supports_fix: - continue + if context_map: + if next_plugin.plugin_id not in context_map: + continue + context = context_map[next_plugin.plugin_id] + # if context.in_fix_mode and not next_plugin.plugin_supports_fix: + # continue try: if context.in_fix_mode: context.set_current_fix_line(None) @@ -1041,14 +1088,19 @@ def next_line( line: str, is_last_line_in_file: bool, was_newline_added_at_end_of_file: bool, + context_map: Optional[Dict[str, PluginScanContext]] = None, ) -> None: """ Inform any listeners that a new line has been loaded. """ context.line_number = line_number for next_plugin in self.__enabled_plugins_for_next_line: - if context.in_fix_mode and not next_plugin.plugin_supports_fix: - continue + if context_map: + if next_plugin.plugin_id not in context_map: + continue + context = context_map[next_plugin.plugin_id] + # if context.in_fix_mode and not next_plugin.plugin_supports_fix: + # continue try: if context.in_fix_mode: self.__next_line_fix_mode_before(context, line, next_plugin) @@ -1075,11 +1127,23 @@ def next_line( # pylint: enable=too-many-arguments - def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None: + def next_token( + self, + context: PluginScanContext, + token: MarkdownToken, + context_map: Optional[Dict[str, PluginScanContext]] = None, + ) -> None: """ Inform any listeners of a new token that has been processed. """ for next_plugin in self.__enabled_plugins_for_next_token: + if context_map: + if next_plugin.plugin_id not in context_map: + continue + context = context_map[next_plugin.plugin_id] + + # if context.in_fix_mode and not next_plugin.plugin_supports_fix: + # continue try: next_plugin.plugin_instance.next_token(context, token) except Exception as this_exception: diff --git a/pymarkdown/plugin_manager/plugin_scan_context.py b/pymarkdown/plugin_manager/plugin_scan_context.py index 7d26b42c0..c68b5a155 100644 --- a/pymarkdown/plugin_manager/plugin_scan_context.py +++ b/pymarkdown/plugin_manager/plugin_scan_context.py @@ -4,7 +4,7 @@ from __future__ import annotations from io import TextIOWrapper -from typing import TYPE_CHECKING, Dict, List, Optional, Union +from typing import TYPE_CHECKING, Dict, List, Optional, Set, Union from typing_extensions import override @@ -188,5 +188,11 @@ def report_on_triggered_rules(self) -> None: self.owning_manager.log_scan_failure(next_entry) self.__reported.clear() + def get_triggered_rules(self) -> Set[str]: + """ + Get information on any rules that were triggered. + """ + return {next_entry.rule_id.lower() for next_entry in self.__reported} + # pylint: enable=too-many-instance-attributes diff --git a/pymarkdown/plugins/rule_md_005.py b/pymarkdown/plugins/rule_md_005.py index e99b24bfa..5c8a4978a 100644 --- a/pymarkdown/plugins/rule_md_005.py +++ b/pymarkdown/plugins/rule_md_005.py @@ -100,6 +100,7 @@ def get_details(self) -> PluginDetailsV2: plugin_version="0.5.0", plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md005.md", plugin_supports_fix=True, + plugin_fix_level=2, ) def starting_new_file(self) -> None: diff --git a/pymarkdown/plugins/rule_md_009.py b/pymarkdown/plugins/rule_md_009.py index 60c5537e8..737014d27 100644 --- a/pymarkdown/plugins/rule_md_009.py +++ b/pymarkdown/plugins/rule_md_009.py @@ -42,6 +42,7 @@ def get_details(self) -> PluginDetails: plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md009.md", plugin_configuration="br_spaces,list_item_empty_lines,strict", plugin_supports_fix=True, + plugin_fix_level=0, ) @classmethod diff --git a/pymarkdown/plugins/rule_md_010.py b/pymarkdown/plugins/rule_md_010.py index 9182cfcc8..5bca61687 100644 --- a/pymarkdown/plugins/rule_md_010.py +++ b/pymarkdown/plugins/rule_md_010.py @@ -39,6 +39,7 @@ def get_details(self) -> PluginDetails: plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md010.md", plugin_configuration="code_blocks", plugin_supports_fix=True, + plugin_fix_level=0, ) def initialize_from_config(self) -> None: diff --git a/pymarkdown/plugins/rule_md_027.py b/pymarkdown/plugins/rule_md_027.py index 73c3b1863..fa484d779 100644 --- a/pymarkdown/plugins/rule_md_027.py +++ b/pymarkdown/plugins/rule_md_027.py @@ -43,10 +43,16 @@ def __init__(self) -> None: self.__line_index_at_bq_start: Optional[int] = None self.__is_paragraph_end_delayed = False self.__delayed_blank_line: Optional[MarkdownToken] = None + self.__delayed_blank_line_bq_index: Optional[int] = None + self.__delayed_blank_line_with_list_end = False self.__have_incremented_for_this_line = False self.__last_token: Optional[MarkdownToken] = None # self.__debug_on = False - self.__frank = ListTracker() + self.__list_tracker = ListTracker() + + self.__delayed_bleading_fixes: Dict[ + MarkdownToken, List[Tuple[int, str, bool, BlankLineMarkdownToken]] + ] = {} def get_details(self) -> PluginDetailsV2: """ @@ -60,6 +66,7 @@ def get_details(self) -> PluginDetailsV2: plugin_version="0.5.0", plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md027.md", plugin_supports_fix=True, + plugin_fix_level=5, ) def starting_new_file(self) -> None: @@ -72,9 +79,11 @@ def starting_new_file(self) -> None: self.__line_index_at_bq_start = None self.__is_paragraph_end_delayed = False self.__delayed_blank_line = None + self.__delayed_blank_line_bq_index = None + self.__delayed_blank_line_with_list_end = False self.__have_incremented_for_this_line = False self.__last_token = None - self.__frank.starting_new_file() + self.__list_tracker.starting_new_file() # pylint: disable=too-many-arguments def __report_issue( @@ -168,10 +177,10 @@ def __report_issue_setext_text( else: whitespace_parts.append(next_line[split_character_index + 1 :]) recombined_whitespace = "\n".join(whitespace_parts) - if recombined_whitespace != text_token.end_whitespace: - self.register_fix_token_request( - context, token, "next_token", "end_whitespace", recombined_whitespace - ) + assert recombined_whitespace != text_token.end_whitespace + self.register_fix_token_request( + context, token, "next_token", "end_whitespace", recombined_whitespace + ) def __report_issue_new_list_item( self, context: PluginScanContext, token: MarkdownToken @@ -189,7 +198,7 @@ def __report_issue_new_list_item( list_start_token.indent_level - adjust_amount, ) # self.register_fix_token_request(context, token, "next_token", "column_number", list_start_token.column_number - adjust_amount) - self.__frank.register(token, adjust_amount) + self.__list_tracker.register(token, adjust_amount) def __report_issue_list_start( self, context: PluginScanContext, token: MarkdownToken @@ -213,7 +222,7 @@ def __report_issue_list_start( "column_number", list_start_token.column_number - adjust_amount, ) - self.__frank.register(token, adjust_amount) + self.__list_tracker.register(token, adjust_amount) def __report_issue_link_reference( self, context: PluginScanContext, token: MarkdownToken @@ -276,12 +285,14 @@ def __process_delayed_paragraph_end( # print("[[Delayed paragraph end processed]]") self.__is_paragraph_end_delayed = False + # pylint: disable=too-many-arguments def __process_delayed_blank_line( self, context: PluginScanContext, token: MarkdownToken, num_container_tokens: int, allow_block_quote_end: bool, + is_block_quote_end: bool, ) -> None: if ( self.__delayed_blank_line @@ -289,13 +300,25 @@ def __process_delayed_blank_line( token.is_leaf_end_token or (allow_block_quote_end and token.is_block_quote_end) ) - and (not self.__have_incremented_for_this_line or token.is_blank_line) + and ( + not self.__have_incremented_for_this_line + or token.is_blank_line + or is_block_quote_end + ) ): self.__have_incremented_for_this_line = False + assert self.__delayed_blank_line_bq_index is not None self.__handle_blank_line( - context, self.__delayed_blank_line, num_container_tokens + context, + self.__delayed_blank_line, + num_container_tokens, + self.__delayed_blank_line_bq_index, ) self.__delayed_blank_line = None + self.__delayed_blank_line_bq_index = None + self.__delayed_blank_line_with_list_end = False + + # pylint: enable=too-many-arguments def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None: """ @@ -334,7 +357,7 @@ def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None: elif token.is_new_list_item: self.__handle_new_list_item(context, token, num_container_tokens) else: - self.__frank.next_token(token) + self.__list_tracker.next_token(token) if num_container_tokens: self.__handle_within_block_quotes(context, token) @@ -351,6 +374,24 @@ def __handle_block_quote_start(self, token: MarkdownToken) -> None: # if self.__debug_on: # print(f"bq>{ParserHelper.make_value_visible(self.__container_tokens[-1])}") + # pylint: disable=too-many-arguments + def __register_blank_line( + self, + token: BlockQuoteMarkdownToken, + index: int, + mod: str, + did_x: bool, + blank_line_token: BlankLineMarkdownToken, + ) -> None: + if token in self.__delayed_bleading_fixes: + delayed_list = self.__delayed_bleading_fixes[token] + else: + delayed_list = [] + self.__delayed_bleading_fixes[token] = delayed_list + delayed_list.append((index, mod, did_x, blank_line_token)) + + # pylint: enable=too-many-arguments + def __handle_block_quote_end( self, context: PluginScanContext, @@ -358,7 +399,9 @@ def __handle_block_quote_end( num_container_tokens: int, ) -> None: self.__process_delayed_paragraph_end(token, num_container_tokens) - self.__process_delayed_blank_line(context, token, num_container_tokens, False) + self.__process_delayed_blank_line( + context, token, num_container_tokens, False, True + ) num_container_tokens = len( [i for i in self.__container_tokens if i.is_block_quote_start] @@ -367,6 +410,38 @@ def __handle_block_quote_end( # print(f"leading_spaces>{ParserHelper.make_value_visible(self.__container_tokens[-1].leading_spaces)}") block_quote_token = cast(BlockQuoteMarkdownToken, self.__container_tokens[-1]) assert block_quote_token.bleading_spaces is not None + + if ( + self.__delayed_bleading_fixes + and block_quote_token in self.__delayed_bleading_fixes + ): + split_leading_spaces = block_quote_token.bleading_spaces.split( + ParserHelper.newline_character + ) + delayed_list = self.__delayed_bleading_fixes[block_quote_token] + for delayed_list_item in delayed_list: + block_quote_index = delayed_list_item[0] + modified_part = delayed_list_item[1] + split_leading_spaces[block_quote_index] = modified_part + + did_trigger = delayed_list_item[2] + if not did_trigger: + blank_token = delayed_list_item[3] + self.report_next_token_error( + context, + blank_token, + column_number_delta=-(blank_token.column_number - 1), + ) + if context.in_fix_mode: + self.register_fix_token_request( + context, + block_quote_token, + "next_token", + "bleading_spaces", + "\n".join(split_leading_spaces), + ) + del self.__delayed_bleading_fixes[block_quote_token] + newlines_in_container = block_quote_token.bleading_spaces.count( ParserHelper.newline_character ) @@ -389,11 +464,11 @@ def __handle_block_quote_end( # print(f"__bq_line_index>{self.__bq_line_index[num_container_tokens]}") # print(f"__is_paragraph_end_delayed>{self.__is_paragraph_end_delayed}") # print(f"__delayed_blank_line>{self.__delayed_blank_line}") - if ( - self.__delayed_blank_line - and newlines_in_container != self.__bq_line_index[num_container_tokens] - ): - self.__bq_line_index[num_container_tokens] += 1 + # if ( + # self.__delayed_blank_line + # and newlines_in_container != self.__bq_line_index[num_container_tokens] + # ): + # self.__bq_line_index[num_container_tokens] += 1 # assert newlines_in_container == self.__bq_line_index[num_container_tokens], ( # str(newlines_in_container) @@ -484,9 +559,11 @@ def __handle_list_start( token: MarkdownToken, num_container_tokens: int, ) -> None: - self.__frank.list_start(token) + self.__list_tracker.list_start(token) - self.__process_delayed_blank_line(context, token, num_container_tokens, False) + self.__process_delayed_blank_line( + context, token, num_container_tokens, False, False + ) self.__process_delayed_paragraph_end(token, num_container_tokens) self.__check_list_starts(context, token, num_container_tokens, False) self.__container_tokens.append(token) @@ -497,7 +574,7 @@ def __handle_new_list_item( token: MarkdownToken, num_container_tokens: int, ) -> None: - self.__frank.new_list_item(token) + self.__list_tracker.new_list_item(token) # if self.__debug_on: # print( # f"num_container_tokens={num_container_tokens}, __is_paragraph_end_delayed=" @@ -516,15 +593,17 @@ def __handle_new_list_item( def __handle_list_end( self, context: PluginScanContext, token: MarkdownToken ) -> None: - self.__frank.list_end() + self.__list_tracker.list_end() + if self.__delayed_blank_line: + self.__delayed_blank_line_with_list_end = True - if registration_map := self.__frank.get_registrations(): + if registration_map := self.__list_tracker.get_registrations(): end_token = cast(EndMarkdownToken, token) list_token = cast(ListStartMarkdownToken, end_token.start_markdown_token) if list_token.leading_spaces: split_leading_spaces = list_token.leading_spaces.split("\n") for registered_token, adj in registration_map.items(): - start, stop = self.__frank.get_start_stop(registered_token) + start, stop = self.__list_tracker.get_start_stop(registered_token) for next_index in range(start, stop): split_leading_spaces[next_index] = ( split_leading_spaces[next_index][:-adj] @@ -541,7 +620,7 @@ def __handle_list_end( rebuilt_leading_spaces, ) - self.__frank.list_end_cleanup() + self.__list_tracker.list_end_cleanup() del self.__container_tokens[-1] def __handle_blank_line( @@ -549,17 +628,61 @@ def __handle_blank_line( context: PluginScanContext, token: MarkdownToken, num_container_tokens: int, + delayed_bq_index: int, ) -> None: # if self.__debug_on: # print(f"__handle_blank_line>>{token}<<") blank_line_token = cast(BlankLineMarkdownToken, token) + + if self.__container_tokens and self.__container_tokens[-1].is_block_quote_start: + scoped_block_quote_token = cast( + BlockQuoteMarkdownToken, self.__container_tokens[-1] + ) + assert scoped_block_quote_token.bleading_spaces is not None + split_leading_spaces = scoped_block_quote_token.bleading_spaces.split( + ParserHelper.newline_character + ) + + # If we are closing other containers, can cause issues. So do not fire. + is_end_with_other_closed_containers = ( + delayed_bq_index == len(split_leading_spaces) - 1 + and self.__delayed_blank_line_with_list_end + ) + + # If we have matching nested block quotes, and then a blank line, we need to prevent + # the firing. + is_special_case = ( + delayed_bq_index == 0 + and len(split_leading_spaces) == 1 + and blank_line_token.line_number != scoped_block_quote_token.line_number + ) + + if ( + not is_special_case + and not is_end_with_other_closed_containers + and delayed_bq_index < len(split_leading_spaces) + ): + specific_block_quote_prefix = split_leading_spaces[delayed_bq_index] + mod_specific_block_quote_prefix = specific_block_quote_prefix.rstrip( + " " + ) + if mod_specific_block_quote_prefix != specific_block_quote_prefix: + self.__register_blank_line( + scoped_block_quote_token, + delayed_bq_index, + mod_specific_block_quote_prefix, + bool(blank_line_token.extracted_whitespace), + blank_line_token, + ) + if blank_line_token.extracted_whitespace: # if self.__debug_on: # print("blank-error") + self.__report_issue(context, token) - if self.__bq_line_index: - self.__bq_line_index[num_container_tokens] += 1 + assert self.__bq_line_index + self.__bq_line_index[num_container_tokens] += 1 def __handle_common_element( self, @@ -908,7 +1031,7 @@ def __scan_text( found_index = next_line.find(ParserHelper.whitespace_split_character) if found_index != -1: next_line = next_line[:found_index] - if next_line: + if next_line and found_index != -1: assert scoped_block_quote_token.bleading_spaces is not None split_leading_spaces = scoped_block_quote_token.bleading_spaces.split( ParserHelper.newline_character @@ -1039,7 +1162,9 @@ def __handle_within_block_quotes_prefix( # print(f"{self.__bq_line_index[num_container_tokens]}-->token>{ParserHelper.make_value_visible(token)}") self.__process_delayed_paragraph_end(token, num_container_tokens) - self.__process_delayed_blank_line(context, token, num_container_tokens, True) + self.__process_delayed_blank_line( + context, token, num_container_tokens, True, False + ) is_directly_within_block_quote = self.__container_tokens[ -1 ].is_block_quote_start @@ -1070,6 +1195,10 @@ def __handle_within_block_quotes( # print("[[Delaying paragraph end]]") elif token.is_blank_line: self.__delayed_blank_line = token + self.__delayed_blank_line_bq_index = self.__bq_line_index[ + num_container_tokens + ] + self.__delayed_blank_line_with_list_end = False # if self.__debug_on: # print("[[Delaying blank line]]") elif token.is_atx_heading or token.is_thematic_break: diff --git a/pymarkdown/plugins/rule_md_030.py b/pymarkdown/plugins/rule_md_030.py index 0850813a3..ccc251fa6 100644 --- a/pymarkdown/plugins/rule_md_030.py +++ b/pymarkdown/plugins/rule_md_030.py @@ -3,7 +3,7 @@ """ from typing import Dict, List, Optional, cast -from pymarkdown.plugin_manager.plugin_details import PluginDetails +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 from pymarkdown.plugins.utils.list_tracker import ListTracker @@ -30,19 +30,19 @@ def __init__(self) -> None: # self.__debug = False self.__frank = ListTracker() - def get_details(self) -> PluginDetails: + def get_details(self) -> PluginDetailsV2: """ Get the details for the plugin. """ - return PluginDetails( + return PluginDetailsV2( plugin_name="list-marker-space", plugin_id="MD030", plugin_enabled_by_default=True, plugin_description="Spaces after list markers", plugin_version="0.5.0", - plugin_interface_version=1, plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md030.md", plugin_configuration="ul_single,ol_single,ul_multi,ol_multi", + plugin_supports_fix=True, ) @classmethod @@ -174,33 +174,46 @@ def __next_token_list_start(self, token: MarkdownToken) -> None: self.__current_list_parent = token self.__frank.list_start(token) + def __next_token_list_end_registrations( + self, + context: PluginScanContext, + token: MarkdownToken, + registration_map: Dict[MarkdownToken, int], + ) -> None: + end_token = cast(EndMarkdownToken, token) + list_token = cast(ListStartMarkdownToken, end_token.start_markdown_token) + if list_token.leading_spaces: + split_leading_spaces = list_token.leading_spaces.split("\n") + for registered_token, adj in registration_map.items(): + start, stop = self.__frank.get_start_stop(registered_token) + for next_index in range(start, stop): + if ( + next_index == len(split_leading_spaces) - 1 + or not split_leading_spaces[next_index] + ): + continue + split_leading_spaces[next_index] = ( + split_leading_spaces[next_index][:-adj] + if adj > 0 + else split_leading_spaces[next_index] + (" " * -adj) + ) + rebuilt_leading_spaces = "\n".join(split_leading_spaces) + if rebuilt_leading_spaces != list_token.leading_spaces: + self.register_fix_token_request( + context, + list_token, + "next_token", + "leading_spaces", + rebuilt_leading_spaces, + ) + def __next_token_list_end( self, context: PluginScanContext, token: MarkdownToken ) -> None: self.__frank.list_end() self.__handle_list_end(context) if registration_map := self.__frank.get_registrations(): - end_token = cast(EndMarkdownToken, token) - list_token = cast(ListStartMarkdownToken, end_token.start_markdown_token) - if list_token.leading_spaces: - split_leading_spaces = list_token.leading_spaces.split("\n") - for registered_token, adj in registration_map.items(): - start, stop = self.__frank.get_start_stop(registered_token) - for next_index in range(start, stop): - split_leading_spaces[next_index] = ( - split_leading_spaces[next_index][:-adj] - if adj > 0 - else split_leading_spaces[next_index] + (" " * -adj) - ) - rebuilt_leading_spaces = "\n".join(split_leading_spaces) - if rebuilt_leading_spaces != list_token.leading_spaces: - self.register_fix_token_request( - context, - list_token, - "next_token", - "leading_spaces", - rebuilt_leading_spaces, - ) + self.__next_token_list_end_registrations(context, token, registration_map) self.__frank.list_end_cleanup() del self.__list_stack[-1] diff --git a/pymarkdown/plugins/rule_md_038.py b/pymarkdown/plugins/rule_md_038.py index c5443f7a8..9ab3b54d0 100644 --- a/pymarkdown/plugins/rule_md_038.py +++ b/pymarkdown/plugins/rule_md_038.py @@ -27,7 +27,6 @@ def get_details(self) -> PluginDetailsV2: plugin_enabled_by_default=True, plugin_description="Spaces inside code span elements", plugin_version="0.5.0", - plugin_interface_version=1, plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md038.md", plugin_supports_fix=True, ) @@ -58,13 +57,12 @@ def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None: adjusted_span_text = adjusted_span_text[1:] if has_trailing: adjusted_span_text = adjusted_span_text[:-1] - if len(adjusted_span_text): - self.register_fix_token_request( - context, - token, - "next_token", - "span_text", - adjusted_span_text, - ) + self.register_fix_token_request( + context, + token, + "next_token", + "span_text", + adjusted_span_text, + ) else: self.report_next_token_error(context, token) diff --git a/pymarkdown/plugins/rule_md_047.py b/pymarkdown/plugins/rule_md_047.py index dc7ac2dd7..816054216 100644 --- a/pymarkdown/plugins/rule_md_047.py +++ b/pymarkdown/plugins/rule_md_047.py @@ -27,6 +27,7 @@ def get_details(self) -> PluginDetails: plugin_version="0.5.0", plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md047.md", plugin_supports_fix=True, + plugin_fix_level=0, ) def starting_new_file(self) -> None: diff --git a/pymarkdown/tokens/block_quote_markdown_token.py b/pymarkdown/tokens/block_quote_markdown_token.py index a4a7b1aa3..c405aa7b7 100644 --- a/pymarkdown/tokens/block_quote_markdown_token.py +++ b/pymarkdown/tokens/block_quote_markdown_token.py @@ -3,7 +3,9 @@ """ import logging -from typing import Dict, Optional +from typing import Dict, Optional, Union + +from typing_extensions import override from pymarkdown.general.parser_helper import ParserHelper from pymarkdown.general.parser_logger import ParserLogger @@ -219,3 +221,11 @@ def __handle_end_block_quote_token( ) token_parts.extend(["", ParserHelper.newline_character]) return "".join(token_parts) + + @override + def _modify_token(self, field_name: str, field_value: Union[str, int]) -> bool: + if field_name == "bleading_spaces" and isinstance(field_value, str): + self.__leading_spaces = field_value + self.__compose_extra_data_field() + return True + return super()._modify_token(field_name, field_value) diff --git a/test/resources/plugins/bad/bad_fix_token_unsupported.py b/test/resources/plugins/bad/bad_fix_token_unsupported.py index 0fddf043e..2355120cd 100644 --- a/test/resources/plugins/bad/bad_fix_token_unsupported.py +++ b/test/resources/plugins/bad/bad_fix_token_unsupported.py @@ -36,6 +36,7 @@ def get_details(self): plugin_description="Plugin that.", plugin_version="0.0.0", plugin_supports_fix=True, + plugin_fix_level=0, ) def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None: diff --git a/test/resources/plugins/bad/bad_next_line_fix.py b/test/resources/plugins/bad/bad_next_line_fix.py index c46292196..fc312d43d 100644 --- a/test/resources/plugins/bad/bad_next_line_fix.py +++ b/test/resources/plugins/bad/bad_next_line_fix.py @@ -28,5 +28,4 @@ def next_line(self, context, line) -> None: """ Event that a new line is being processed. """ - if context.in_fix_mode: - self.report_next_line_error(context, 0, -1) + self.report_next_line_error(context, 0, -1) diff --git a/test/resources/plugins/bad/bad_update_last_line.py b/test/resources/plugins/bad/bad_update_last_line.py index 403b3fe23..d96212e02 100644 --- a/test/resources/plugins/bad/bad_update_last_line.py +++ b/test/resources/plugins/bad/bad_update_last_line.py @@ -24,6 +24,7 @@ def get_details(self): plugin_description="Plugin that has always adds a newline.", plugin_version="0.0.0", plugin_supports_fix=True, + plugin_fix_level=0, ) def completed_file(self, context: PluginScanContext) -> None: diff --git a/test/resources/rules/md027/good_block_quote_empty_just_blank.md b/test/resources/rules/md027/good_block_quote_empty_just_blank.md index c0c497ce0..d9e80f6f7 100644 --- a/test/resources/rules/md027/good_block_quote_empty_just_blank.md +++ b/test/resources/rules/md027/good_block_quote_empty_just_blank.md @@ -1 +1 @@ -> +> diff --git a/test/resources/rules/md027/good_block_quote_indent_with_blank_space.md b/test/resources/rules/md027/good_block_quote_indent_with_blank_space.md index b42d87e25..33f309cb7 100644 --- a/test/resources/rules/md027/good_block_quote_indent_with_blank_space.md +++ b/test/resources/rules/md027/good_block_quote_indent_with_blank_space.md @@ -1,3 +1,3 @@ > this is text -> +> > within a block quote diff --git a/test/rules/test_md001.py b/test/rules/test_md001.py index c2c465336..31a48422b 100644 --- a/test/rules/test_md001.py +++ b/test/rules/test_md001.py @@ -2,452 +2,111 @@ Module to provide tests related to the MD001 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, +) import pytest source_path = os.path.join("test", "resources", "rules", "md001") + os.sep - -@pytest.mark.rules -def test_md001_all_samples(): - """ - Test to make sure we get the expected behavior after scanning all the files in the - test/resources/rules/md001 directory. Note that with three front-matter files in - this directory and no config to enable that extension, Md022 will report bad - heading formats. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "--disable-rules", - "MD003", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}front_matter_with_alternate_title.md:2:1: " - + "MD022: Headings should be surrounded by blank lines. " - + "[Expected: 1; Actual: 0; Above] (blanks-around-headings,blanks-around-headers)\n" - + f"{source_path}front_matter_with_no_title.md:2:1: " - + "MD022: Headings should be surrounded by blank lines. " - + "[Expected: 1; Actual: 0; Above] (blanks-around-headings,blanks-around-headers)\n" - + f"{source_path}front_matter_with_title.md:2:1: " - + "MD022: Headings should be surrounded by blank lines. " - + "[Expected: 1; Actual: 0; Above] (blanks-around-headings,blanks-around-headers)\n" - + f"{source_path}improper_atx_heading_incrementing.md:3:1: " - + "MD001: Heading levels should only increment by one level at a time. " - + "[Expected: h2; Actual: h3] (heading-increment,header-increment)\n" - + f"{source_path}improper_setext_heading_incrementing.md:4:1: " - + "MD001: Heading levels should only increment by one level at a time. " - + "[Expected: h3; Actual: h4] (heading-increment,header-increment)\n" - ) - 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_md001_bad_configuration_enabled(): - """ - Test to verify that enabling front matter with text "True" fails. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "--strict-config", - "--set", - "extensions.front-matter.enabled=True", - "scan", - f"{source_path}front_matter_with_title.md", - ] - - expected_return_code = 1 - expected_output = "" - expected_error = """Configuration error ValueError encountered while initializing extensions: -The value for property 'extensions.front-matter.enabled' must be of type 'bool'.""" - - # 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_md001_bad_configuration_front_matter_title(): - """ - Test to verify that enabling front matter title with number "1" fails. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "--strict-config", - "--set", - "extensions.front-matter.enabled=$!True", - "--set", - "plugins.md001.front_matter_title=$#1", - "scan", - f"{source_path}proper_atx_heading_incrementing.md", - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md001.front_matter_title' must be of type 'str'." - ) - - # 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_md001_empty_configuration_front_matter_title(): - """ - Test to verify that enabling front matter title with "" is okay. - Note that since nothing in the front matter is considered a title, - then there is nothing to compare the first heading element to. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "--strict-config", - "--set", - "extensions.front-matter.enabled=$!True", - "--set", - "plugins.md001.front_matter_title=", - "scan", - f"{source_path}front_matter_with_title.md", - ] - - 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_md001_good_proper_atx_heading_incrementing(): - """ - Test to make sure the rule doesn't trigger with a document with - only Atx Headings, that when they increase, only increase by 1. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "scan", - f"{source_path}proper_atx_heading_incrementing.md", - ] - - 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_md001_good_proper_setext_heading_incrementing(): - """ - Test to make sure the rule doesn't trigger with a document with - only SetExt Headings, that when they increase, only increase by 1. - Note that after the first 2 headings, it switches over to Atx Headings. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "--disable-rules", - "MD003", - "scan", - f"{source_path}proper_setext_heading_incrementing.md", - ] - - 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_md001_bad_improper_atx_heading_incrementing(): - """ - Test to make sure the rule does trigger with a document with - only Atx Headings, that when they increase, only increase by 2. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "scan", - f"{source_path}improper_atx_heading_incrementing.md", - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}improper_atx_heading_incrementing.md:3:1: " - + "MD001: Heading levels should only increment by one level at a time. " - + "[Expected: h2; Actual: h3] (heading-increment,header-increment)\n" - ) - 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_md001_bad_improper_atx_heading_incrementing_fix(): - """ - Test to make sure the rule does trigger with a document with - only Atx Headings, that when they increase, only increase by 2. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "improper_atx_heading_incrementing.md" - ) as temp_source_path: - original_file_contents = """# Heading 1 +extension_enable_front_matter = "extensions.front-matter.enabled=$!True" +plug_set_front_matter_title_to_subject = "plugins.md001.front_matter_title=Subject" + +extension_set_invalid_enable_front_matter_as_string = ( + "extensions.front-matter.enabled=True" +) +plugin_set_invalid_front_matter_title = "plugins.md001.front_matter_title=$#1" + +__plugin_disable_md003 = "md003" + +configTests = [ + pluginConfigErrorTest( + "enable_front_matter_with_string", + use_strict_config=True, + set_args=[extension_set_invalid_enable_front_matter_as_string], + expected_error="""Configuration error ValueError encountered while initializing extensions: +The value for property 'extensions.front-matter.enabled' must be of type 'bool'.""", + ), + pluginConfigErrorTest( + "plugin_set_invalid_front_matter_title", + use_strict_config=True, + set_args=[extension_enable_front_matter, plugin_set_invalid_front_matter_title], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md001.front_matter_title' must be of type 'str'.""", + ), +] + + +scanTests = [ + pluginRuleTest( + "empty_configuration_front_matter_title", + source_file_name=f"{source_path}front_matter_with_title.md", + set_args=[extension_enable_front_matter, "plugins.md001.front_matter_title="], + ), + pluginRuleTest( + "good_proper_atx_heading_incrementing", + source_file_name=f"{source_path}proper_atx_heading_incrementing.md", + ), + pluginRuleTest( + "good_proper_setext_heading_incrementing", + source_file_name=f"{source_path}proper_setext_heading_incrementing.md", + disable_rules=__plugin_disable_md003, + ), + pluginRuleTest( + "bad_improper_atx_heading_incrementing", + source_file_name=f"{source_path}improper_atx_heading_incrementing.md", + source_file_contents="""# Heading 1 ### Heading 3 We skipped out a 2nd level heading in this document -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - # "-x-fix-debug", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = """# Heading 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:3:1: MD001: Heading levels should only increment by one level at a time. [Expected: h2; Actual: h3] (heading-increment,header-increment)\n", + fix_expected_file_contents="""# Heading 1 ## Heading 3 We skipped out a 2nd level heading in this document -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md001_bad_improper_setext_heading_incrementing(): - """ - Test to make sure the rule does trigger with a document with - only SetExt Headings (and Atx Headings after level 2), that when they - increase, only increase by 2. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "--disable-rules", - "MD003", - "scan", - f"{source_path}improper_setext_heading_incrementing.md", - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}improper_setext_heading_incrementing.md:4:1: " - + "MD001: Heading levels should only increment by one level at a time. " - + "[Expected: h3; Actual: h4] (heading-increment,header-increment)\n" - ) - 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_md001_bad_improper_setext_heading_incrementing_fix(): - """ - Test to make sure the rule does trigger with a document with - only SetExt Headings (and Atx Headings after level 2), that when they - increase, only increase by 2. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "improper_setext_heading_incrementing.md" - ) as temp_source_path: - original_file_contents = """Heading 2 +""", + ), + pluginRuleTest( + "bad_improper_setext_heading_incrementing", + source_file_name=f"{source_path}improper_setext_heading_incrementing.md", + disable_rules=__plugin_disable_md003, + source_file_contents="""Heading 2 --------- #### Heading 4 We skipped out a heading level in this document -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - supplied_arguments = [ - "--disable-rules", - "MD003", - "-x-fix", - # "-x-fix-debug", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = """Heading 2 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:4:1: MD001: Heading levels should only increment by one level at a time. [Expected: h3; Actual: h4] (heading-increment,header-increment)\n", + fix_expected_file_contents="""Heading 2 --------- ### Heading 4 We skipped out a heading level in this document -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md001_front_matter_with_no_title(): - """ - Test to make sure the rule does not trigger with a document with - a front-matter element with no title and the front matter extension - enabled, and a following Atx Heading of level 3. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "--set", - "extensions.front-matter.enabled=$!True", - "scan", - f"{source_path}front_matter_with_no_title.md", - ] - - 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_md001_front_matter_with_title(): - """ - Test to make sure the rule does trigger with a document with - a front-matter element with a title and the front matter extension - enabled, and a following Atx Heading of level 3. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "--set", - "extensions.front-matter.enabled=$!True", - "scan", - f"{source_path}front_matter_with_title.md", - ] - - expected_return_code = 1 - expected_output = f"{source_path}front_matter_with_title.md:5:1: MD001: Heading levels should only increment by one level at a time. [Expected: h2; Actual: h3] (heading-increment,header-increment)\n" - 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_md001_front_matter_with_title_fix(): - """ - Test to make sure the rule does trigger with a document with - a front-matter element with a title and the front matter extension - enabled, and a following Atx Heading of level 3. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "front_matter_with_title.md" - ) as temp_source_path: - original_file_contents = """--- +""", + ), + pluginRuleTest( + "front_matter_with_no_title", + source_file_name=f"{source_path}front_matter_with_no_title.md", + set_args=[extension_enable_front_matter], + ), + pluginRuleTest( + "front_matter_with_title", + source_file_name=f"{source_path}front_matter_with_title.md", + set_args=[extension_enable_front_matter], + source_file_contents="""--- title: field --- @@ -455,21 +114,10 @@ def test_md001_front_matter_with_title_fix(): We skipped out a 2nd level heading in this document, which should only kick in if there is a title field in the front matter. -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - supplied_arguments = [ - "--set", - "extensions.front-matter.enabled=$!True", - "-x-fix", - # "-x-fix-debug", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = """--- +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:5:1: MD001: Heading levels should only increment by one level at a time. [Expected: h2; Actual: h3] (heading-increment,header-increment)\n", + fix_expected_file_contents="""--- title: field --- @@ -477,62 +125,16 @@ def test_md001_front_matter_with_title_fix(): We skipped out a 2nd level heading in this document, which should only kick in if there is a title field in the front matter. -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md001_front_matter_with_alternate_title(): - """ - Variation of test_md001_front_matter_with_title using configuration - to specify an alternate title. - """ - - # Arrange - scanner = MarkdownScanner() - supplied_arguments = [ - "--set", - "extensions.front-matter.enabled=$!True", - "--set", - "plugins.md001.front_matter_title=Subject", - "scan", - f"{source_path}front_matter_with_alternate_title.md", - ] - - expected_return_code = 1 - expected_output = f"{source_path}front_matter_with_alternate_title.md:5:1: MD001: Heading levels should only increment by one level at a time. [Expected: h2; Actual: h3] (heading-increment,header-increment)\n" - 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_md001_front_matter_with_alternate_title_fix(): - """ - Variation of test_md001_front_matter_with_title using configuration - to specify an alternate title. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "front_matter_with_alternate_title.md" - ) as temp_source_path: - original_file_contents = """--- +""", + ), + pluginRuleTest( + "front_matter_with_alternate_title", + source_file_name=f"{source_path}front_matter_with_alternate_title.md", + set_args=[ + extension_enable_front_matter, + plug_set_front_matter_title_to_subject, + ], + source_file_contents="""--- Subject: field --- @@ -540,23 +142,10 @@ def test_md001_front_matter_with_alternate_title_fix(): We skipped out a 2nd level heading in this document, which should only kick in if there is a title field in the front matter. -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - supplied_arguments = [ - "--set", - "extensions.front-matter.enabled=$!True", - "--set", - "plugins.md001.front_matter_title=Subject", - "-x-fix", - # "-x-fix-debug", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = """--- +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:5:1: MD001: Heading levels should only increment by one level at a time. [Expected: h2; Actual: h3] (heading-increment,header-increment)\n", + fix_expected_file_contents="""--- Subject: field --- @@ -564,13 +153,34 @@ def test_md001_front_matter_with_alternate_title_fix(): We skipped out a 2nd level heading in this document, which should only kick in if there is a title field in the front matter. -""" +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md001_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md001") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md001_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) + + +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md001_config(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_configuration_test(test, f"{source_path}front_matter_with_title.md") diff --git a/test/rules/test_md004.py b/test/rules/test_md004.py index 6e6047bcc..3da0e31ab 100644 --- a/test/rules/test_md004.py +++ b/test/rules/test_md004.py @@ -2,939 +2,195 @@ Module to provide tests related to the MD004 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, +) import pytest source_path = os.path.join("test", "resources", "rules", "md004") + os.sep - -@pytest.mark.rules -def test_md004_bad_configuration_style(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with a string that is not in the list of acceptable values. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_asterisk_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=bad", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md004.style' is not valid: Allowable values: ['consistent', 'asterisk', 'plus', 'dash', 'sublist']" - ) - - # 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_md004_good_asterisk_single_level(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 unordered lists starting with asterisk and the - configuration is set to asterisk. - - This function shadows - test_api_config_with_good_string_property - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_asterisk_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=asterisk", - "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_md004_good_asterisk_single_level_consistent(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 unordered lists starting with asterisk and the - configuration is set to consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_asterisk_single_level.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_md004_bad_asterisk_dash_single_level(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_dash_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=asterisk", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: asterisk; Actual: dash] (ul-style)" - ) - 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_md004_bad_asterisk_dash_single_level_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_list_dash_single_level.md" - ) as temp_source_path: - original_file_contents = """- first +set_style_asterisk = "plugins.md004.style=asterisk" +set_style_dash = "plugins.md004.style=dash" +set_style_plus = "plugins.md004.style=plus" +set_style_sublist = "plugins.md004.style=sublist" + +__plugin_enable_md006 = "MD006" + +__plugin_disable_md007 = "MD007" +__plugin_disable_md032 = "md032" + +configTests = [ + pluginConfigErrorTest( + "invalid_style", + use_strict_config=True, + set_args=["plugins.md004.style=bad"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md004.style' is not valid: Allowable values: ['consistent', 'asterisk', 'plus', 'dash', 'sublist']""", + ), +] + + +scanTests = [ + pluginRuleTest( + "good_asterisk_single_level", + source_file_name=f"{source_path}good_list_asterisk_single_level.md", + set_args=[set_style_asterisk], + ), + pluginRuleTest( + "good_asterisk_single_level_consistent", + source_file_name=f"{source_path}good_list_asterisk_single_level.md", + set_args=[], + ), + pluginRuleTest( + "bad_asterisk_dash_single_level", + source_file_name=f"{source_path}good_list_dash_single_level.md", + set_args=[set_style_asterisk], + source_file_contents="""- first - second - third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md004.style=asterisk", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* first +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:1: MD004: Inconsistent Unordered List Start style [Expected: asterisk; Actual: dash] (ul-style)", + fix_expected_file_contents="""* first * second * third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md004_bad_asterisk_plus_single_level(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with plus and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_plus_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=asterisk", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: asterisk; Actual: plus] (ul-style)" - ) - 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_md004_bad_asterisk_plus_single_level_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_list_plus_single_level.md" - ) as temp_source_path: - original_file_contents = """+ first +""", + ), + pluginRuleTest( + "bad_asterisk_plus_single_level", + source_file_name=f"{source_path}good_list_plus_single_level.md", + set_args=[set_style_asterisk], + source_file_contents="""+ first + second + third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md004.style=asterisk", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* first +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:1: MD004: Inconsistent Unordered List Start style [Expected: asterisk; Actual: plus] (ul-style)", + fix_expected_file_contents="""* first * second * third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md004_good_dash_single_level(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to dash. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_dash_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=dash", - "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_md004_good_dash_single_level_consistent(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_dash_single_level.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_md004_bad_dash_asterisk_single_level(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with asterisks and the - configuration is also set to dash. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_asterisk_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=dash", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: dash; Actual: asterisk] (ul-style)" - ) - 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_md004_bad_dash_asterisk_single_level_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_list_asterisk_single_level.md" - ) as temp_source_path: - original_file_contents = """* first +""", + ), + pluginRuleTest( + "good_dash_single_level", + source_file_name=f"{source_path}good_list_dash_single_level.md", + set_args=[set_style_dash], + ), + pluginRuleTest( + "good_dash_single_level_consistent", + source_file_name=f"{source_path}good_list_dash_single_level.md", + set_args=[], + ), + pluginRuleTest( + "bad_dash_asterisk_single_level", + source_file_name=f"{source_path}good_list_asterisk_single_level.md", + set_args=[set_style_dash], + source_file_contents="""* first * second * third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md004.style=dash", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """- first +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:1: MD004: Inconsistent Unordered List Start style [Expected: dash; Actual: asterisk] (ul-style)", + fix_expected_file_contents="""- first - second - third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md004_bad_dash_plus_single_level(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with plus and the - configuration is also set to dash. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_plus_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=dash", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: dash; Actual: plus] (ul-style)" - ) - 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_md004_bad_dash_plus_single_level_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_list_plus_single_level.md" - ) as temp_source_path: - original_file_contents = """+ first +""", + ), + pluginRuleTest( + "bad_dash_plus_single_level", + source_file_name=f"{source_path}good_list_plus_single_level.md", + set_args=[set_style_dash], + source_file_contents="""+ first + second + third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md004.style=dash", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """- first +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:1: MD004: Inconsistent Unordered List Start style [Expected: dash; Actual: plus] (ul-style)", + fix_expected_file_contents="""- first - second - third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md004_good_plus_single_level(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 unordered lists starting with plus and the - configuration is also set to plus. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_plus_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=plus", - "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_md004_good_plus_single_level_consistent(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_plus_single_level.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_md004_bad_plus_asterisk_single_level(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 unordered lists starting with asterisk and the - configuration is also set to plus. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_asterisk_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=plus", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: plus; Actual: asterisk] (ul-style)" - ) - 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_md004_good_plus_single_level_consistent_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_list_asterisk_single_level.md" - ) as temp_source_path: - original_file_contents = """* first +""", + ), + pluginRuleTest( + "good_plus_single_level", + source_file_name=f"{source_path}good_list_plus_single_level.md", + set_args=[set_style_plus], + ), + pluginRuleTest( + "good_plus_single_level_consistent", + source_file_name=f"{source_path}good_list_plus_single_level.md", + set_args=[], + ), + pluginRuleTest( + "bad_plus_asterisk_single_level", + source_file_name=f"{source_path}good_list_asterisk_single_level.md", + set_args=[set_style_plus], + source_file_contents="""* first * second * third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md004.style=plus", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ first +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:1: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: asterisk] (ul-style)", + fix_expected_file_contents="""+ first + second + third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md004_bad_plus_dash_single_level(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to plus. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_dash_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=plus", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: plus; Actual: dash] (ul-style)" - ) - 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_md004_bad_plus_dash_single_level_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_list_dash_single_level.md" - ) as temp_source_path: - original_file_contents = """- first +""", + ), + pluginRuleTest( + "bad_plus_dash_single_level", + source_file_name=f"{source_path}good_list_dash_single_level.md", + set_args=[set_style_plus], + source_file_contents="""- first - second - third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md004.style=plus", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ first +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:1: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style)", + fix_expected_file_contents="""+ first + second + third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md004_bad_single_level_consistent(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with each of the valid starts. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "bad_list_different_single_level.md" - ) - supplied_arguments = [ - "--disable-rules", - "md032", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: asterisk; Actual: plus] (ul-style)\n" - + f"{source_path}:3:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: asterisk; Actual: dash] (ul-style)" - ) - 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_md004_bad_single_level_consistent_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_different_single_level.md" - ) as temp_source_path: - original_file_contents = """* first +""", + ), + pluginRuleTest( + "bad_single_level_consistent", + source_file_name=f"{source_path}bad_list_different_single_level.md", + set_args=[], + disable_rules=__plugin_disable_md032, + source_file_contents="""* first + second - third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* first +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:2:1: MD004: Inconsistent Unordered List Start style [Expected: asterisk; Actual: plus] (ul-style)\n" + + "{temp_source_path}:3:1: MD004: Inconsistent Unordered List Start style [Expected: asterisk; Actual: dash] (ul-style)" + ), + fix_expected_file_contents="""* first * second * third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md004_good_multi_level_sublevel(): - """ - Test to make sure this rule does not trigger with a document that contains - the three start characters, each on their own sublevel. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_multi_level_sublevel.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=sublist", - "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_md004_good_multi_level_sublevel_complex(): - """ - Variation of the previous test with a more complex list structure. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_multi_level_complex.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=sublist", - "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_md004_bad_multi_level_sublevel_complex(): - """ - Test to make sure this rule does trigger with a document that contains - the inconsistent start characters at one specific sublevel. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "bad_multi_level_complex.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=sublist", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:6: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: dash; Actual: plus] (ul-style)" - ) - 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_md004_bad_multi_level_sublevel_complex_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_multi_level_complex.md" - ) as temp_source_path: - original_file_contents = """+ first +""", + ), + pluginRuleTest( + "good_multi_level_sublevel", + source_file_name=f"{source_path}good_multi_level_sublevel.md", + set_args=[set_style_sublist], + ), + pluginRuleTest( + "good_multi_level_sublevel_complex", + source_file_name=f"{source_path}good_multi_level_complex.md", + set_args=[set_style_sublist], + ), + pluginRuleTest( + "bad_multi_level_sublevel_complex", + source_file_name=f"{source_path}bad_multi_level_complex.md", + set_args=[set_style_sublist], + source_file_contents="""+ first 1. second - third + first @@ -946,22 +202,10 @@ def test_md004_bad_multi_level_sublevel_complex_fix(): 1. fourth * fifth + third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md004.style=sublist", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ first +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:6:6: MD004: Inconsistent Unordered List Start style [Expected: dash; Actual: plus] (ul-style)", + fix_expected_file_contents="""+ first 1. second - third + first @@ -973,75 +217,13 @@ def test_md004_bad_multi_level_sublevel_complex_fix(): 1. fourth * fifth - third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md004_bad_multi_level_sublevel_complex_asterisk(): - """ - Test to make sure this rule does trigger with a document that contains - the three start characters, each on their own sublevel, and configuration - specifically set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "bad_multi_level_complex.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=asterisk", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: asterisk; Actual: plus] (ul-style)\n" - + f"{source_path}:3:6: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: asterisk; Actual: dash] (ul-style)\n" - + f"{source_path}:6:6: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: asterisk; Actual: plus] (ul-style)" - ) - 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_md004_bad_multi_level_sublevel_complex_asterisk_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_multi_level_complex.md" - ) as temp_source_path: - original_file_contents = """+ first +""", + ), + pluginRuleTest( + "bad_multi_level_sublevel_complex_asterisk", + source_file_name=f"{source_path}bad_multi_level_complex.md", + set_args=[set_style_asterisk], + source_file_contents="""+ first 1. second - third + first @@ -1053,22 +235,14 @@ def test_md004_bad_multi_level_sublevel_complex_asterisk_fix(): 1. fourth * fifth + third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md004.style=asterisk", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* first +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:1:1: MD004: Inconsistent Unordered List Start style [Expected: asterisk; Actual: plus] (ul-style)\n" + + "{temp_source_path}:3:6: MD004: Inconsistent Unordered List Start style [Expected: asterisk; Actual: dash] (ul-style)\n" + + "{temp_source_path}:6:6: MD004: Inconsistent Unordered List Start style [Expected: asterisk; Actual: plus] (ul-style)" + ), + fix_expected_file_contents="""* first 1. second * third * first @@ -1080,104 +254,138 @@ def test_md004_bad_multi_level_sublevel_complex_asterisk_fix(): 1. fourth * fifth * third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md004_bad_dual_lists_with_separator(): - """ - Test to make sure this rule does trigger with a document that contains - two separate lists with different start characters, and configuration - specifically set to sublist. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "bad_dual_lists_with_separator.md" - ) - supplied_arguments = [ - "--set", - "plugins.md004.style=sublist", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:1: " - + "MD004: Inconsistent Unordered List Start style " - + "[Expected: plus; Actual: asterisk] (ul-style)" - ) - 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_md004_bad_dual_lists_with_separator_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_dual_lists_with_separator.md" - ) as temp_source_path: - original_file_contents = """+ item 1 +""", + ), + pluginRuleTest( + "bad_dual_lists_with_separator", + source_file_name=f"{source_path}bad_dual_lists_with_separator.md", + set_args=[set_style_sublist], + source_file_contents="""+ item 1 - item 1a this is a separator * item 2 - item 2a -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md004.style=sublist", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ item 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:6:1: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: asterisk] (ul-style)", + fix_expected_file_contents="""+ item 1 - item 1a this is a separator + item 2 - item 2a -""" +""", + ), + pluginRuleTest( + "mix_md004_md006", + is_mix_test=True, + use_debug=True, + enable_rules=__plugin_enable_md006, + disable_rules=__plugin_disable_md007, + source_file_contents=""" + first + * second + - third + * first + - second + + third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left) +{temp_source_path}:2:4: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: asterisk] (ul-style) +{temp_source_path}:3:6: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +{temp_source_path}:4:2: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left) +{temp_source_path}:5:4: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +""", + fix_expected_file_contents="""+ first + + second + + third ++ first + + second + + third +""", + ), + pluginRuleTest( + "mix_md004_md007", + source_file_contents=""" + first + * second + - third + * first + - second + + third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:2:4: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: asterisk] (ul-style) +{temp_source_path}:2:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent) +{temp_source_path}:3:6: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +{temp_source_path}:3:6: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent) +{temp_source_path}:4:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:5:4: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +{temp_source_path}:5:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent) +{temp_source_path}:6:6: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent) +""", + fix_expected_file_contents="""+ first + + second + + third ++ first + + second + + third +""", + ), + pluginRuleTest( + "mix_md004_md032", + source_file_contents="""+ first + * second + - third +* first + - second + + third +----- +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: asterisk] (ul-style) +{temp_source_path}:3:5: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +{temp_source_path}:5:3: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +{temp_source_path}:6:1: MD032: Lists should be surrounded by blank lines (blanks-around-lists) +""", + fix_expected_file_contents="""+ first + + second + + third ++ first + + second + + third +----- +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md004_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md004") - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md004_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) + + +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md004_config(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_configuration_test(test, f"{source_path}good_list_asterisk_single_level.md") diff --git a/test/rules/test_md005.py b/test/rules/test_md005.py index 2065d7f84..1748c9063 100644 --- a/test/rules/test_md005.py +++ b/test/rules/test_md005.py @@ -2,2311 +2,522 @@ Module to provide tests related to the MD005 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import ( - assert_file_is_as_expected, - copy_to_temp_file, - create_temporary_configuration_file, +from test.rules.utils import ( + build_fix_and_clash_lists, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, ) import pytest source_path = os.path.join("test", "resources", "rules", "md005") + os.sep - -@pytest.mark.rules -def test_md005_good_unordered_list_single_level(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 unordered lists with no indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "good_unordered_list_single_level.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_md005_bad_unordered_list_single_level(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists with 1 indent before the second list. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "bad_unordered_list_single_level.md" - ) - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:2: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 0; Actual: 1] (list-indent)" - ) - 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_md005_bad_unordered_list_single_level_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_list_single_level.md" - ) as temp_source_path: - original_file_contents = """* Item 1 +__plugin_disable_md007 = "md007" +__plugin_disable_md007_md027 = "md007,md027" +__plugin_disable_md007_md029 = "md007,md029" +__plugin_disable_md029 = "md029" +__plugin_disable_md029_md030 = "md029,md030" +__plugin_disable_md033 = "md033" + +scanTests = [ + pluginRuleTest( + "good_unordered_list_single_level", + source_file_name=f"{source_path}good_unordered_list_single_level.md", + ), + pluginRuleTest( + "bad_unordered_list_single_level", + source_file_name=f"{source_path}bad_unordered_list_single_level.md", + disable_rules=__plugin_disable_md007, + source_file_contents="""* Item 1 * Item 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:2:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)", + fix_expected_file_contents="""* Item 1 * Item 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_good_unordered_list_double_level(): - """ - Test to make sure this rule does not trigger with a document that - is level 1 and 2 unordered lists, both with consistent left-aligned - indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "good_unordered_list_double_level.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_md005_bad_unordered_list_double_level_bad_first(): - """ - Test to make sure this rule does trigger with a document that - is has level 1 and 2 unordered lists with inconsistent indentation - at the first level. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_unordered_list_double_level_bad_first.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:2: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 0; Actual: 1] (list-indent)\n" - + f"{source_path}:5:4: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 2; Actual: 3] (list-indent)\n" - + f"{source_path}:6:4: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 2; Actual: 3] (list-indent)" - ) - 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_md005_bad_unordered_list_double_level_bad_first_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_list_double_level_bad_first.md" - ) as temp_source_path: - original_file_contents = """* Item 1 +""", + ), + pluginRuleTest( + "good_unordered_list_double_level", + source_file_name=f"{source_path}good_unordered_list_double_level.md", + ), + pluginRuleTest( + "bad_unordered_list_double_level_bad_first", + source_file_name=f"{source_path}bad_unordered_list_double_level_bad_first.md", + disable_rules=__plugin_disable_md007, + source_file_contents="""* Item 1 * Item 1a * Item 1b * Item 2 * Item 2a * Item 2b -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* Item 1 - * Item 1a - * Item 1b -* Item 2 - * Item 2a - * Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_unordered_list_double_level_bad_second(): - """ - Test to make sure this rule does trigger with a document that - is has level 1 and 2 unordered lists with inconsistent indentation - at the second level. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_unordered_list_double_level_bad_second.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:4: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 2; Actual: 3] (list-indent)" - ) - 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_md005_bad_unordered_list_double_level_bad_second_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_list_double_level_bad_second.md" - ) as temp_source_path: - original_file_contents = """* Item 1 - * Item 1a - * Item 1b -* Item 2 - * Item 2a - * Item 2b -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* Item 1 +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:4:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)\n" + + "{temp_source_path}:5:4: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 3] (list-indent)\n" + + "{temp_source_path}:6:4: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 3] (list-indent)" + ), + fix_expected_file_contents="""* Item 1 * Item 1a * Item 1b * Item 2 * Item 2a * Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_good_unordered_list_separate_lists(): - """ - Test to make sure this rule does not trigger with a document that - has level 1 and 2 unordered lists with consistent indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "good_unordered_list_separate_lists.md" - ) - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "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_md005_bad_unordered_list_single_level_twice(): - """ - Test to make sure this rule does trigger with a document that - has multiple level 1 unordered lists with inconsistent indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_unordered_list_single_level_twice.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:2: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 0; Actual: 1] (list-indent)\n" - + f"{source_path}:3:2: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 0; Actual: 1] (list-indent)" - ) - 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_md005_bad_unordered_list_single_level_twice_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_list_single_level_twice.md" - ) as temp_source_path: - original_file_contents = """* Item 1 - * Item 2 - * Item 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* Item 1 -* Item 2 -* Item 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_good_ordered_list_single_level(): - """ - Test to make sure this rule does not trigger with a document that - has level 1 ordered lists with consistent indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "good_ordered_list_single_level.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_md005_bad_ordered_list_single_level_x(): - """ - Test to make sure this rule does trigger with a document that - has level 1 ordered lists with inconsistent indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "bad_ordered_list_single_level.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:2: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 0; Actual: 1] (list-indent)" - ) - 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_md005_bad_ordered_list_single_level_x_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_single_level.md" - ) as temp_source_path: - original_file_contents = """1. Item 1 - 1. Item 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 -1. Item 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_good_ordered_list_single_level_widths(): - """ - Test to make sure this rule does not trigger with a document that - has level 1 ordered lists with consistent indentation with either - left or right alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "good_ordered_list_single_level_widths.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "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_md005_bad_ordered_list_single_level_widths(): - """ - Test to make sure this rule does trigger with a document that - has level 1 ordered lists with inconsistent indentation with either - left alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "bad_ordered_list_single_level_widths.md" - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:2: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 0; Actual: 1] (list-indent)" - ) - 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_md005_bad_ordered_list_single_level_widths_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_single_level.md" - ) as temp_source_path: - original_file_contents = """1. Item 1 - 1. Item 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 -1. Item 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_good_ordered_list_single_level_widths_right(): - """ - Test to make sure this rule does not trigger with a document that - has level 1 ordered lists with consistent indentation and right alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "good_ordered_list_single_level_widths_right.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "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_md005_bad_ordered_list_single_level_widths_right(): - """ - Test to make sure this rule does trigger with a document that - has level 1 ordered lists with inconsistent indentation with either - right alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_ordered_list_single_level_widths_right.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 3; Actual: 0] (list-indent)" - ) - 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_md005_bad_ordered_list_single_level_widths_right_fix(): - """ - Test to make sure this rule does trigger with a document that - has level 1 ordered lists with inconsistent indentation with either - right alignment. - - Note that the first line does not start a right aligned list as it is - way too out of sync with line 2. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_single_level_widths_right.md" - ) as temp_source_path: - original_file_contents = """ 1. Item 1 -10. Item 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ 1. Item 1 - 10. Item 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_good_ordered_list_single_level_short_widths_right(): - """ - Test to make sure this rule does not trigger with a document that - has level 1 ordered lists with consistent indentation and right alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "good_ordered_list_single_level_short_widths_right.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "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_md005_good_ordered_list_separate_single_level_short_widths_right(): - """ - Test to make sure this rule does not trigger with a document that - has two level 1 ordered lists with consistent indentation and right alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "good_ordered_list_seperate_single_level_short_widths_right.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "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_md005_good_ordered_list_separate_single_level_short_widths(): - """ - Test to make sure this rule does not trigger with a document that - has two level 1 ordered lists with consistent indentation and left alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "good_ordered_list_seperate_single_level_short_widths.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029,md030", - "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_md005_good_ordered_list_double_level(): - """ - Test to make sure this rule does not trigger with a document that - has two level 1 ordered lists with consistent indentation and left alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "good_ordered_list_double_level.md" - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "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_md005_good_ordered_list_double_level_right(): - """ - Test to make sure this rule does not trigger with a document that - has two level 1 ordered lists with consistent indentation and right alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "good_ordered_list_double_level_right.md" - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "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_md005_bad_ordered_list_double_level_weirdx(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with consistent indentation and weird alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "bad_ordered_list_double_level_weird.md" - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:5: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 3; Actual: 4] (list-indent)" - ) - 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_md005_bad_ordered_list_double_level_weirdx_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_double_level_weird.md" - ) as temp_source_path: - original_file_contents = """1. Item 1 - 1. Item 1a - 100. Item 1b -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 - 1. Item 1a - 100. Item 1b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_list_double_level_weirder(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with consistent indentation and weirder alignment. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_ordered_list_double_level_weirder.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 0; Actual: 2] (list-indent)" - ) - 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_md005_bad_ordered_list_double_level_weirder_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_double_level_weirder.md" - ) as temp_source_path: - original_file_contents = """1. Item 1 - 1. Item 1a - 100. Item 1b -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 - 1. Item 1a -100. Item 1b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_good_unordered_list_double_level_in_block_quote(): - """ - Test to make sure this rule does not trigger with a document that - has level 1 and 2 unordered lists with consistent indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "good_unordered_list_double_level_in_block_quote.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_md005_good_unordered_list_double_level_in_block_quote_first(): - """ - Test to make sure this rule does not trigger with a document that - has level 1 and 2 unordered lists with consistent indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_unordered_list_double_level_in_block_quote_first.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007,md027,md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:4: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 2; Actual: 3] (list-indent)" - ) - 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_md005_good_unordered_list_double_level_in_block_quote_second(): - """ - Test to make sure this rule does not trigger with a document that - has level 1 and 2 unordered lists with consistent indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_unordered_list_double_level_in_block_quote_second.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:6: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 4; Actual: 5] (list-indent)\n" - + f"{source_path}:6:6: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 4; Actual: 5] (list-indent)" - ) - 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_md005_bad_ordered_list_double_level_left(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with left alignment and bad indentation - on the second list. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "bad_ordered_list_double_level_left.md" - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:5: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 3; Actual: 4] (list-indent)\n" - + f"{source_path}:6:5: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 3; Actual: 4] (list-indent)" - ) - 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_md005_bad_ordered_list_double_level_left_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_double_level_left.md" - ) as temp_source_path: - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_unordered_list_double_level_bad_second", + source_file_name=f"{source_path}bad_unordered_list_double_level_bad_second.md", + disable_rules=__plugin_disable_md007, + source_file_contents="""* Item 1 + * Item 1a + * Item 1b +* Item 2 + * Item 2a + * Item 2b +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:6:4: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 3] (list-indent)", + fix_expected_file_contents="""* Item 1 + * Item 1a + * Item 1b +* Item 2 + * Item 2a + * Item 2b +""", + ), + pluginRuleTest( + "good_unordered_list_separate_lists", + source_file_name=f"{source_path}good_unordered_list_separate_lists.md", + disable_rules=__plugin_disable_md007, + ), + pluginRuleTest( + "bad_unordered_list_single_level_twice", + source_file_name=f"{source_path}bad_unordered_list_single_level_twice.md", + disable_rules=__plugin_disable_md007, + source_file_contents="""* Item 1 + * Item 2 + * Item 2 +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:2:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)\n" + + "{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)" + ), + fix_expected_file_contents="""* Item 1 +* Item 2 +* Item 2 +""", + ), + pluginRuleTest( + "good_ordered_list_single_level", + source_file_name=f"{source_path}good_ordered_list_single_level.md", + ), + pluginRuleTest( + "bad_ordered_list_single_level_x", + source_file_name=f"{source_path}bad_ordered_list_single_level.md", + source_file_contents="""1. Item 1 + 1. Item 2 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:2:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)", + fix_expected_file_contents="""1. Item 1 +1. Item 2 +""", + ), + pluginRuleTest( + "good_ordered_list_single_level_widths", + source_file_name=f"{source_path}good_ordered_list_single_level_widths.md", + disable_rules=__plugin_disable_md029, + ), + pluginRuleTest( + "bad_ordered_list_single_level_widths", + source_file_name=f"{source_path}bad_ordered_list_single_level_widths.md", + disable_rules=__plugin_disable_md029, + source_file_contents="""1. Item 1 + 100. Item 3 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:2:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)", + fix_expected_file_contents="""1. Item 1 +100. Item 3 +""", + ), + pluginRuleTest( + "good_ordered_list_single_level_widths_right", + source_file_name=f"{source_path}good_ordered_list_single_level_widths_right.md", + disable_rules=__plugin_disable_md029, + ), + pluginRuleTest( + "bad_ordered_list_single_level_widths_right", + source_file_name=f"{source_path}bad_ordered_list_single_level_widths_right.md", + disable_rules=__plugin_disable_md029, + source_file_contents=""" 1. Item 1 +10. Item 2 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:2:1: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 0] (list-indent)", + fix_expected_file_contents=""" 1. Item 1 + 10. Item 2 +""", + ), + pluginRuleTest( + "good_ordered_list_single_level_short_widths_right", + source_file_name=f"{source_path}good_ordered_list_single_level_short_widths_right.md", + disable_rules=__plugin_disable_md029, + ), + pluginRuleTest( + "good_ordered_list_separate_single_level_short_widths_right", + source_file_name=f"{source_path}good_ordered_list_seperate_single_level_short_widths_right.md", + disable_rules=__plugin_disable_md029, + ), + pluginRuleTest( + "good_ordered_list_separate_single_level_short_widths", + source_file_name=f"{source_path}good_ordered_list_seperate_single_level_short_widths.md", + disable_rules=__plugin_disable_md029_md030, + ), + pluginRuleTest( + "good_ordered_list_double_level", + source_file_name=f"{source_path}good_ordered_list_double_level.md", + disable_rules=__plugin_disable_md029, + ), + pluginRuleTest( + "good_ordered_list_double_level_right", + source_file_name=f"{source_path}good_ordered_list_double_level_right.md", + disable_rules=__plugin_disable_md029, + ), + pluginRuleTest( + "bad_ordered_list_double_level_weirdx", + source_file_name=f"{source_path}bad_ordered_list_double_level_weird.md", + disable_rules=__plugin_disable_md029, + source_file_contents="""1. Item 1 + 1. Item 1a + 100. Item 1b +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:3:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent)", + fix_expected_file_contents="""1. Item 1 + 1. Item 1a + 100. Item 1b +""", + ), + pluginRuleTest( + "bad_ordered_list_double_level_weirder", + source_file_name=f"{source_path}bad_ordered_list_double_level_weirder.md", + disable_rules=__plugin_disable_md029, + source_file_contents="""1. Item 1 + 1. Item 1a + 100. Item 1b +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:3:3: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 2] (list-indent)", + fix_expected_file_contents="""1. Item 1 + 1. Item 1a +100. Item 1b +""", + ), + pluginRuleTest( + "good_unordered_list_double_level_in_block_quote", + source_file_name=f"{source_path}good_unordered_list_double_level_in_block_quote.md", + ), + pluginRuleTest( + "bad_unordered_list_double_level_in_block_quote_first", + source_file_name=f"{source_path}bad_unordered_list_double_level_in_block_quote_first.md", + disable_rules=__plugin_disable_md007_md027, + source_file_contents="""> * Item 1 +> * Item 1a +> * Item 1b +> * Item 2 +> * Item 2a +> * Item 2b +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:4:4: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 3] (list-indent)", + fix_expected_file_contents="""> * Item 1 +> * Item 1a +> * Item 1b +> * Item 2 +> * Item 2a +> * Item 2b +""", + ), + pluginRuleTest( + "bad_unordered_list_double_level_in_block_quote_second", + source_file_name=f"{source_path}bad_unordered_list_double_level_in_block_quote_second.md", + disable_rules=__plugin_disable_md007, + source_file_contents="""> * Item 1 +> * Item 1a +> * Item 1b +> * Item 2 +> * Item 2a +> * Item 2b +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:5:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent)\n" + + "{temp_source_path}:6:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent)", + fix_expected_file_contents="""> * Item 1 +> * Item 1a +> * Item 1b +> * Item 2 +> * Item 2a +> * Item 2b +""", + ), + pluginRuleTest( + "bad_ordered_list_double_level_left", + source_file_name=f"{source_path}bad_ordered_list_double_level_left.md", + disable_rules=__plugin_disable_md029, + source_file_contents="""1. Item 1 1. Item 1a 10. Item 1b 2. Item 2 1. Item 2a 10. Item 2b -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:5:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent)\n" + + "{temp_source_path}:6:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent)" + ), + fix_expected_file_contents="""1. Item 1 1. Item 1a 10. Item 1b 2. Item 2 1. Item 2a 10. Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_list_double_level_right_x(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with right alignment and bad indentation - on the second list. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md005", "bad_ordered_list_double_level_right.md" - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:6: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 4; Actual: 5] (list-indent)\n" - + f"{source_path}:6:5: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 3; Actual: 4] (list-indent)" - ) - 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_md005_bad_ordered_list_double_level_right_x_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_double_level_right.md" - ) as temp_source_path: - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_list_double_level_right_x", + source_file_name=f"{source_path}bad_ordered_list_double_level_right.md", + disable_rules=__plugin_disable_md029, + source_file_contents="""1. Item 1 1. Item 1a 10. Item 1b 2. Item 2 1. Item 2a 10. Item 2b -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:5:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent)\n" + + "{temp_source_path}:6:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent)" + ), + fix_expected_file_contents="""1. Item 1 1. Item 1a 10. Item 1b 2. Item 2 1. Item 2a 10. Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_list_double_level_left_then_right(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with left alignment on the first list - and right alignment on the second list. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_ordered_list_double_level_left_then_right.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:5: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 3; Actual: 4] (list-indent)" - ) - 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_md005_bad_ordered_list_double_level_left_then_right_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_double_level_left_then_right.md" - ) as temp_source_path: - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_list_double_level_left_then_right", + source_file_name=f"{source_path}bad_ordered_list_double_level_left_then_right.md", + disable_rules=__plugin_disable_md029, + source_file_contents="""1. Item 1 1. Item 1a 10. Item 1b 2. Item 2 1. Item 2a 10. Item 2b -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:5:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent)", + fix_expected_file_contents="""1. Item 1 1. Item 1a 10. Item 1b 2. Item 2 1. Item 2a 10. Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_list_double_level_right_then_left(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with right alignment on the first list - and left alignment on the second list. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_ordered_list_double_level_right_then_left.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:4: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 4; Actual: 3] (list-indent)" - ) - 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_md005_bad_ordered_list_double_level_right_then_left_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_double_level_right_then_left.md" - ) as temp_source_path: - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_list_double_level_right_then_left", + source_file_name=f"{source_path}bad_ordered_list_double_level_right_then_left.md", + disable_rules=__plugin_disable_md029, + source_file_contents="""1. Item 1 1. Item 1a 10. Item 1b 2. Item 2 1. Item 2a 10. Item 2b -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:5:4: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 3] (list-indent)", + fix_expected_file_contents="""1. Item 1 1. Item 1a 10. Item 1b 2. Item 2 1. Item 2a 10. Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_list_single_level_left_then_right(): - """ - Test to make sure this rule does trigger with a document that - has a single level 1 ordered list with left alignment on the first - two list items and right alignment on the third item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_ordered_list_single_level_left_then_right.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:2: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 0; Actual: 1] (list-indent)" - ) - 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_md005_bad_ordered_list_single_level_left_then_right_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_single_level_left_then_right.md" - ) as temp_source_path: - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_list_single_level_left_then_right", + source_file_name=f"{source_path}bad_ordered_list_single_level_left_then_right.md", + disable_rules=__plugin_disable_md029, + source_file_contents="""1. Item 1 10. Item 2 2. Item 3 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)", + fix_expected_file_contents="""1. Item 1 10. Item 2 2. Item 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_list_single_level_right_then_left(): - """ - Test to make sure this rule does trigger with a document that - has a single level 1 ordered list with right alignment on the first - two list items and left alignment on the third item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md005", - "bad_ordered_list_single_level_right_then_left.md", - ) - supplied_arguments = [ - "--disable-rules", - "md029", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:1: " - + "MD005: Inconsistent indentation for list items at the same level " - + "[Expected: 1; Actual: 0] (list-indent)" - ) - 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_md005_bad_ordered_list_single_level_right_then_left_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_ordered_list_single_level_right_then_left.md" - ) as temp_source_path: - original_file_contents = """ 1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_list_single_level_right_then_left", + source_file_name=f"{source_path}bad_ordered_list_single_level_right_then_left.md", + disable_rules=__plugin_disable_md029, + source_file_contents=""" 1. Item 1 10. Item 2 2. Item 3 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ 1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:3:1: MD005: Inconsistent indentation for list items at the same level [Expected: 1; Actual: 0] (list-indent)", + fix_expected_file_contents=""" 1. Item 1 10. Item 2 2. Item 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_left_unordered_x(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with right alignment and bad indentation - on the second list. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """1. Item 1 - + Item 1a - + Item 1b - 10. Item 2 - + Item 2a - + Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md029,md007", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:4:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) -{path}:5:6: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 5] (list-indent) -{path}:6:6: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 5] (list-indent) -""".replace( - "{path}", temp_source_path - ) - 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_md005_bad_ordered_left_unordered_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_left_unordered_x", + disable_rules=__plugin_disable_md007_md029, + source_file_contents="""1. Item 1 + Item 1a + Item 1b 10. Item 2 + Item 2a + Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:5:6: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 5] (list-indent) +{temp_source_path}:6:6: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 5] (list-indent) +""", + fix_expected_file_contents="""1. Item 1 + Item 1a + Item 1b 10. Item 2 + Item 2a + Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_right_unordered_x(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with right alignment and bad indentation - on the second list. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """ 1. Item 1 - + Item 1a - + Item 1b - 10. Item 2 - + Item 2a - + Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md029,md007", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:5:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent) -{path}:6:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent) -""".replace( - "{path}", temp_source_path - ) - 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 -@pytest.mark.skip -def test_md005_bad_ordered_right_unordered_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """ 1. Item 1 - + Item 1a - + Item 1b - 10. Item 2 - + Item 2a - + Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ 1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_right_unordered_x", + disable_rules=__plugin_disable_md007_md029, + source_file_contents=""" 1. Item 1 + Item 1a + Item 1b 10. Item 2 + Item 2a + Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_unordered_ordered_left_x(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with right alignment and bad indentation - on the second list. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """+ Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent) +{temp_source_path}:6:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent) +""", + # fix_expected_file_contents=""" 1. Item 1 + # + Item 1a + # + Item 1b + # 10. Item 2 + # + Item 2a + # + Item 2b + # """, + ), + pluginRuleTest( + "bad_unordered_ordered_left_x", + disable_rules=__plugin_disable_md007_md029, + source_file_contents="""+ Item 1 1. Item 1a - 10. Item 1b - + Item 2 - 1. Item 2a - 10. Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md029,md007", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:4:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) -{path}:5:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent) -{path}:6:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent) -""".replace( - "{path}", temp_source_path - ) - 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_md005_bad_unordered_ordered_left_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """+ Item 1 - 1. Item 1a - 10. Item 1b + 10. Item 1b + Item 2 1. Item 2a 10. Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ Item 1 - 1. Item 1a - 10. Item 1b +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:5:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent) +{temp_source_path}:6:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent) +""", + fix_expected_file_contents="""+ Item 1 + 1. Item 1a + 10. Item 1b + Item 2 - 1. Item 2a - 10. Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_unordered_ordered_right_x(): - """ - Test to make sure this rule does trigger with a document that - has two level 1 ordered lists with right alignment and bad indentation - on the second list. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """+ Item 1 + 1. Item 2a + 10. Item 2b +""", + ), + pluginRuleTest( + "bad_unordered_ordered_right_x", + disable_rules=__plugin_disable_md007_md029, + source_file_contents="""+ Item 1 1. Item 1a 10. Item 1b + Item 2 1. Item 2a 10. Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md029,md007", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:4:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) -{path}:5:6: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 5] (list-indent) -{path}:6:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent) -""".replace( - "{path}", temp_source_path - ) - 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 -@pytest.mark.skip -def test_md005_bad_unordered_ordered_right_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """+ Item 1 - 1. Item 1a - 10. Item 1b - + Item 2 - 1. Item 2a - 10. Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ Item 1 - 1. Item 1a - 10. Item 1b -+ Item 2 - 1. Item 2a - 10. Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_unordered_lt_with_text_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """+ Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:5:6: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 5] (list-indent) +{temp_source_path}:6:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent) +""", + # fix_expected_file_contents="""+ Item 1 + # 1. Item 1a + # 10. Item 1b + # + Item 2 + # 1. Item 2a + # 10. Item 2b + # """, + ), + pluginRuleTest( + "bad_unordered_lt_with_text_fix", + disable_rules=__plugin_disable_md007, + source_file_contents="""+ Item 1 more Item 1 + Item 2 more Item 2 -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)""", + fix_expected_file_contents="""+ Item 1 more Item 1 + Item 2 more Item 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_unordered_lt_with_double_text_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """+ Item 1 +""", + ), + pluginRuleTest( + "bad_unordered_lt_with_double_text_fix", + disable_rules=__plugin_disable_md007, + source_file_contents="""+ Item 1 more Item 1 + Item 2 more Item 2 + Item 3 more Item 3 -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:5:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)""", + fix_expected_file_contents="""+ Item 1 more Item 1 + Item 2 more Item 2 + Item 3 more Item 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_unordered_lt_with_text_nested_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """+ Item 1 +""", + ), + pluginRuleTest( + "bad_unordered_lt_with_text_nested_fix", + disable_rules=__plugin_disable_md007, + source_file_contents="""+ Item 1 more Item 1 + Item 1a more Item 1a @@ -2318,23 +529,12 @@ def test_md005_bad_unordered_lt_with_text_nested_fix(): more Item 2a + Item 2b more Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:7:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:9:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent) +{temp_source_path}:11:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent)""", + fix_expected_file_contents="""+ Item 1 more Item 1 + Item 1a more Item 1a @@ -2346,125 +546,49 @@ def test_md005_bad_unordered_lt_with_text_nested_fix(): more Item 2a + Item 2b more Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_unordered_gt_with_text_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """ + Item 1 +""", + ), + pluginRuleTest( + "test_md005_bad_unordered_gt_with_text_fix", + disable_rules=__plugin_disable_md007, + source_file_contents=""" + Item 1 more Item 1 + Item 2 more Item 2 -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ + Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 1] (list-indent)""", + fix_expected_file_contents=""" + Item 1 more Item 1 + Item 2 more Item 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_unordered_gt_with_double_text_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """ + Item 1 +""", + ), + pluginRuleTest( + "bad_unordered_gt_with_double_text_fix", + disable_rules=__plugin_disable_md007, + source_file_contents=""" + Item 1 more Item 1 + Item 2 more Item 2 + Item 3 more Item 3 -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ + Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 1] (list-indent) +{temp_source_path}:5:2: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 1] (list-indent)""", + fix_expected_file_contents=""" + Item 1 more Item 1 + Item 2 more Item 2 + Item 3 more Item 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_unordered_gt_with_text_nested_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """+ Item 1 +""", + ), + pluginRuleTest( + "bad_unordered_gt_with_text_nested_fix", + disable_rules=__plugin_disable_md007, + source_file_contents="""+ Item 1 more Item 1 + Item 1a more Item 1a @@ -2476,23 +600,12 @@ def test_md005_bad_unordered_gt_with_text_nested_fix(): more Item 2a + Item 2b more Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:7:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:9:4: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 3] (list-indent) +{temp_source_path}:11:4: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 3] (list-indent)""", + fix_expected_file_contents="""+ Item 1 more Item 1 + Item 1a more Item 1a @@ -2504,175 +617,67 @@ def test_md005_bad_unordered_gt_with_text_nested_fix(): more Item 2a + Item 2b more Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_lt_with_text_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_lt_with_text_fix", + source_file_contents="""1. Item 1 more Item 1 1. Item 2 more Item 2 -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)""", + fix_expected_file_contents="""1. Item 1 more Item 1 1. Item 2 more Item 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_lt_with_double_text_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_lt_with_double_text_fix", + source_file_contents="""1. Item 1 more Item 1 2. Item 2 more Item 2 3. Item 3 more Item 3 -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:5:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)""", + fix_expected_file_contents="""1. Item 1 more Item 1 2. Item 2 more Item 2 3. Item 3 more Item 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_lt_with_double_text_with_raw_html_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_lt_with_double_text_with_raw_html_fix", + disable_rules=__plugin_disable_md033, + source_file_contents="""1. Item 1 more Item 1 2. Item 2 and inline HTML 3. Item 3 more Item 3 -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:5:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent)""", + fix_expected_file_contents="""1. Item 1 more Item 1 2. Item 2 and inline HTML 3. Item 3 more Item 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_lt_with_text_nested_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_lt_with_text_nested_fix", + source_file_contents="""1. Item 1 more Item 1 1. Item 1a more Item 1a @@ -2684,23 +689,12 @@ def test_md005_bad_ordered_lt_with_text_nested_fix(): more Item 2a 2. Item 2b more Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:7:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:9:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent) +{temp_source_path}:11:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent)""", + fix_expected_file_contents="""1. Item 1 more Item 1 1. Item 1a more Item 1a @@ -2712,125 +706,47 @@ def test_md005_bad_ordered_lt_with_text_nested_fix(): more Item 2a 2. Item 2b more Item 2b -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_gt_with_text_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """ 1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_gt_with_text_fix", + source_file_contents=""" 1. Item 1 more Item 1 2. Item 2 more Item 2 -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ 1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 1] (list-indent)""", + fix_expected_file_contents=""" 1. Item 1 more Item 1 2. Item 2 more Item 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_gt_with_double_text_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """ 1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_gt_with_double_text_fix", + disable_rules=__plugin_disable_md029, + source_file_contents=""" 1. Item 1 more Item 1 2. Item 2 more Item 2 2. Item 3 more Item 3 -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ 1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 1] (list-indent) +{temp_source_path}:5:2: MD005: Inconsistent indentation for list items at the same level [Expected: 2; Actual: 1] (list-indent)""", + fix_expected_file_contents=""" 1. Item 1 more Item 1 2. Item 2 more Item 2 2. Item 3 more Item 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md005_bad_ordered_gt_with_text_nested_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 unordered lists starting with dash and the - configuration is also set to asterisk. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """1. Item 1 +""", + ), + pluginRuleTest( + "bad_ordered_gt_with_text_nested_fix", + source_file_contents="""1. Item 1 more Item 1 1. Item 1a more Item 1a @@ -2842,23 +758,12 @@ def test_md005_bad_ordered_gt_with_text_nested_fix(): more Item 2a 2. Item 2b more Item 2b -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md007,md029", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Item 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:7:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:9:5: MD005: Inconsistent indentation for list items at the same level [Expected: 5; Actual: 4] (list-indent) +{temp_source_path}:11:5: MD005: Inconsistent indentation for list items at the same level [Expected: 5; Actual: 4] (list-indent)""", + fix_expected_file_contents="""1. Item 1 more Item 1 1. Item 1a more Item 1a @@ -2870,13 +775,128 @@ def test_md005_bad_ordered_gt_with_text_nested_fix(): more Item 2a 2. Item 2b more Item 2b -""" +""", + ), + pluginRuleTest( + "mix_md005_md007", + source_file_contents=""" + first + + second + + third ++ first + + second + + third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:2:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent) +{temp_source_path}:3:6: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent) +{temp_source_path}:4:1: MD005: Inconsistent indentation for list items at the same level [Expected: 1; Actual: 0] (list-indent) +{temp_source_path}:5:3: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 2] (list-indent) +{temp_source_path}:6:5: MD005: Inconsistent indentation for list items at the same level [Expected: 5; Actual: 4] (list-indent) +""", + fix_expected_file_contents="""+ first + + second + + third ++ first + + second + + third +""", + ), + pluginRuleTest( + "mix_md005_md027", + source_file_contents="""> * Heading 1 +> * Heading 2 +""", + disable_rules=__plugin_disable_md007, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:2:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent) +""", + fix_expected_file_contents="""> * Heading 1 +> * Heading 2 +""", + ), + pluginRuleTest( + "mix_md005_md029", + source_file_contents="""1. Heading 1 + 9. Heading 2 + 1. Heading 2 + 9. Heading 2 +""", + disable_rules=__plugin_disable_md007, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:2:2: MD029: Ordered list item prefix [Expected: 2; Actual: 9; Style: 1/2/3] (ol-prefix) +{temp_source_path}:4:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent) +{temp_source_path}:4:6: MD029: Ordered list item prefix [Expected: 2; Actual: 9; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. Heading 1 +2. Heading 2 + 1. Heading 2 + 2. Heading 2 +""", + ), + pluginRuleTest( + "mix_md005_md030", + source_file_contents="""+ Heading 1 + + Heading 2 + + Heading 3 + + Heading 4 +""", + disable_rules=__plugin_disable_md007, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:2: MD005: Inconsistent indentation for list items at the same level [Expected: 1; Actual: 1] (list-indent) +{temp_source_path}:2:2: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:5: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:4:6: MD005: Inconsistent indentation for list items at the same level [Expected: 5; Actual: 5] (list-indent) +{temp_source_path}:4:6: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""+ Heading 1 ++ Heading 2 + + Heading 3 + + Heading 4 +""", + ), +] +fixTests, clashTests = build_fix_and_clash_lists(scanTests) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md005_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md005") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md005_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) + + +@pytest.mark.rules +@pytest.mark.skip +def test_md005_bad_ordered_right_unordered_fix(): + """ + Test to make sure this rule does trigger with a document that + is only level 1 unordered lists starting with dash and the + configuration is also set to asterisk. + """ + + # see "bad_ordered_right_unordered_x" - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +@pytest.mark.rules +@pytest.mark.skip +def test_md005_bad_unordered_ordered_right_fix(): + """ + Test to make sure this rule does trigger with a document that + is only level 1 unordered lists starting with dash and the + configuration is also set to asterisk. + """ + # see "bad_ordered_right_unordered_x" diff --git a/test/rules/test_md006.py b/test/rules/test_md006.py index 591e79b81..4009aa908 100644 --- a/test/rules/test_md006.py +++ b/test/rules/test_md006.py @@ -2,854 +2,234 @@ Module to provide tests related to the MD006 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, +) import pytest source_path = os.path.join("test", "resources", "rules", "md006") + os.sep - -@pytest.mark.rules -def test_md006_good_indentation(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 lists with no indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "good_indentation.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "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_md006_good_indentation_in_block_quote(): - """ - Test to make sure this rule does not trigger with a document that - is only level 1 lists with no indentation, in a block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "good_indentation_in_block_quote.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "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_md006_bad_indentation_x(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 lists with a single space of indentation. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "bad_indentation.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "MD007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:2: MD006: " - + "Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" - + f"{source_path}:2:2: MD006: " - + "Consider starting bulleted lists at the beginning of the line (ul-start-left)" - ) - 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_md006_bad_indentation_x_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 lists with a single space of indentation. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_indentation.md") as temp_source_path: - original_file_contents = """ * First Item +plugin_enable_this_rule = "MD006" + +__plugin_disable_md004 = "md004" +__plugin_disable_md007 = "MD007" +__plugin_disable_md005_md007 = "md005,MD007" +__plugin_disable_md007_md027 = "MD007,md027" + +scanTests = [ + pluginRuleTest( + "good_indentation", + source_file_name=f"{source_path}good_indentation.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "good_indentation_in_block_quote", + source_file_name=f"{source_path}good_indentation_in_block_quote.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "bad_indentation_x", + source_file_name=f"{source_path}bad_indentation.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md007, + source_file_contents=""" * First Item * Second Item -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "MD007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First Item +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:1:2: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" + + "{temp_source_path}:2:2: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)" + ), + fix_expected_file_contents="""* First Item * Second Item -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md006_good_indentation_unordered(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 lists with a single space of indentation. - - Note that this rule only applied to unordered lists, so this - should not generated any errors. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "bad_indentation_unordered.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "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_md006_bad_indentation_in_block_quote(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 lists with a single space of indentation, all - in a block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "bad_indentation_in_block_quote.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "MD007,md027", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:4: MD006: " - + "Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" - + f"{source_path}:2:4: MD006: " - + "Consider starting bulleted lists at the beginning of the line (ul-start-left)" - ) - 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_md006_bad_indentation_in_block_quote_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 lists with a single space of indentation. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_indentation_in_block_quote.md" - ) as temp_source_path: - original_file_contents = """> * First Item +""", + ), + pluginRuleTest( + "good_indentation_unordered", + source_file_name=f"{source_path}bad_indentation_unordered.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "bad_indentation_in_block_quote", + source_file_name=f"{source_path}bad_indentation_in_block_quote.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md007_md027, + source_file_contents="""> * First Item > * Second Item -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "MD007,md027", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> * First Item +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:1:4: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" + + "{temp_source_path}:2:4: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)" + ), + fix_expected_file_contents="""> * First Item > * Second Item -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md006_bad_ignore_bad_second_level(): - """ - Test to make sure this rule does not trigger with a document that - is nested lists with level 1 lists properly indented. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "good_ignore_bad_second_level.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "MD005,Md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:4: " - + "MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" - + f"{source_path}:4:5: " - + "MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)" - ) - 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_md006_bad_ignore_bad_second_level_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 lists with a single space of indentation. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_ignore_bad_second_level.md" - ) as temp_source_path: - original_file_contents = """* First Item +""", + ), + pluginRuleTest( + "bad_ignore_bad_second_level", + source_file_name=f"{source_path}good_ignore_bad_second_level.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md005_md007, + source_file_contents="""* First Item * First-First * First-Second * First-Third * Second Item -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "MD005,Md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First Item +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:3:4: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" + + "{temp_source_path}:4:5: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)" + ), + fix_expected_file_contents="""* First Item * First-First * First-Second * First-Third * Second Item -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md006_good_not_ordered(): - """ - Test to make sure this rule does not trigger with a document that - is ordered lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "good_not_ordered.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "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_md006_good_items_with_multiple_lines(): - """ - Test to make sure this rule does not trigger with a document that - is contains list items with multiple lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "good_items_with_multiple_lines.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "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_md006_good_items_with_multiple_lines_in_block_quote(): - """ - Test to make sure this rule does not trigger with a document that - is contains list items with multiple lines, in a block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md006", - "good_items_with_multiple_lines_in_block_quote.md", - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "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_md006_good_indentation_ordered_in_unordered(): - """ - TBD - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md006", - "good_indentation_ordered_in_unordered.md", - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "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_md006_good_indentation_unordered_in_ordered(): - """ - TBD - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md006", - "good_indentation_unordered_in_ordered.md", - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "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_md006_bad_indentation_ordered_in_unordered(): - """ - TBD - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "bad_indentation_ordered_in_unordered.md" - ) - supplied_arguments = [ - "--disable-rules", - "MD007", - "--enable-rules", - "MD006", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:2: " - + "MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)" - ) - 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_md006_bad_indentation_ordered_in_unordered_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 lists with a single space of indentation. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_indentation_ordered_in_unordered.md" - ) as temp_source_path: - original_file_contents = """ * First Item +""", + ), + pluginRuleTest( + "good_not_ordered", + source_file_name=f"{source_path}good_not_ordered.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "good_items_with_multiple_lines", + source_file_name=f"{source_path}good_items_with_multiple_lines.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "good_items_with_multiple_lines_in_block_quote", + source_file_name=f"{source_path}good_items_with_multiple_lines_in_block_quote.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "good_indentation_ordered_in_unordered", + source_file_name=f"{source_path}good_indentation_ordered_in_unordered.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "good_indentation_unordered_in_ordered", + source_file_name=f"{source_path}good_indentation_unordered_in_ordered.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "bad_indentation_ordered_in_unordered", + source_file_name=f"{source_path}bad_indentation_ordered_in_unordered.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md007, + source_file_contents=""" * First Item 1. Second Item -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "MD007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First Item +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:2: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)", + fix_expected_file_contents="""* First Item 1. Second Item -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md006_bad_indentation_unordered_in_ordered(): - """ - TBD - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "bad_indentation_unordered_in_ordered.md" - ) - supplied_arguments = [ - "--disable-rules", - "MD007", - "--enable-rules", - "MD006", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:6: " - + "MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)" - ) - 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_md006_bad_indentation_unordered_in_ordered_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 lists with a single space of indentation. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_indentation_unordered_in_ordered.md" - ) as temp_source_path: - original_file_contents = """ 1. First Item +""", + ), + pluginRuleTest( + "bad_indentation_unordered_in_ordered", + source_file_name=f"{source_path}bad_indentation_unordered_in_ordered.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md007, + source_file_contents=""" 1. First Item - Second Item -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "MD007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ 1. First Item +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:2:6: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)", + fix_expected_file_contents=""" 1. First Item - Second Item -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md006_good_indentation_nested(): - """ - TBD - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "good_indentation_nested.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD006", - "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_md006_bad_indentation_nested(): - """ - TBD - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md006", "bad_indentation_nested.md" - ) - supplied_arguments = [ - "--disable-rules", - "MD007", - "--enable-rules", - "MD006", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:4: " - + "MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" - + f"{source_path}:3:4: " - + "MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" - + f"{source_path}:5:4: " - + "MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" - + f"{source_path}:6:4: " - + "MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)" - ) - 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_md006_bad_indentation_nested_fix(): - """ - Test to make sure this rule does trigger with a document that - is only level 1 lists with a single space of indentation. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_indentation_nested.md" - ) as temp_source_path: - original_file_contents = """- top level 1 +""", + ), + pluginRuleTest( + "good_indentation_nested", + source_file_name=f"{source_path}good_indentation_nested.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "bad_indentation_nested", + source_file_name=f"{source_path}bad_indentation_nested.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md007, + source_file_contents="""- top level 1 - First Item - Second Item - top level 2 - First Item - Second Item -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "MD007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """- top level 1 +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:2:4: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" + + "{temp_source_path}:3:4: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" + + "{temp_source_path}:5:4: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)\n" + + "{temp_source_path}:6:4: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left)" + ), + fix_expected_file_contents="""- top level 1 - First Item - Second Item - top level 2 - First Item - Second Item -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md006_issue_478(): - """ - TBD - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join("test", "resources", "rules", "md006", "issue_478.md") - supplied_arguments = [ - "--enable-rules", - "MD006", - "--disable-rules", - "md004,MD007", - "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 - ) +""", + ), + pluginRuleTest( + "issue_478", + source_file_name=f"{source_path}issue_478.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md004, + ), + pluginRuleTest( + "mix_md006_md004", + is_mix_test=True, + enable_rules="MD006", + disable_rules="MD007", + source_file_contents=""" + first + * second + - third + * first + - second + + third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left) +{temp_source_path}:2:4: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: asterisk] (ul-style) +{temp_source_path}:3:6: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +{temp_source_path}:4:2: MD006: Consider starting bulleted lists at the beginning of the line (ul-start-left) +{temp_source_path}:5:4: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +""", + fix_expected_file_contents="""+ first + + second + + third ++ first + + second + + third +""", + ), +] + +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md006_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md006") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md006_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) diff --git a/test/rules/test_md007.py b/test/rules/test_md007.py index d5ba15297..15dbc8d78 100644 --- a/test/rules/test_md007.py +++ b/test/rules/test_md007.py @@ -2,8 +2,14 @@ Module to provide tests related to the MD007 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, +) import pytest @@ -11,2033 +17,398 @@ source_path = os.path.join("test", "resources", "rules", "md007") + os.sep - -@pytest.mark.rules -def test_md007_bad_configuration_indent(): - """ - Test to verify that a configuration error is thrown when supplying the - indent value with a string that is not an integer. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "good_list_indentation.md" - ) - supplied_arguments = [ - "--set", - "plugins.md007.indent=bad", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md007.indent' must be of type 'int'." - ) - - # 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_md007_bad_configuration_start_indented(): - """ - Test to verify that a configuration error is thrown when supplying the - start_indented value with a value that is not a boolean. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "good_list_indentation.md" - ) - supplied_arguments = [ - "--set", - "plugins.md007.start_indented=bad", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md007.start_indented' must be of type 'bool'." - ) - - # 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_md007_bad_configuration_indent_bad(): - """ - Test to verify that a configuration error is thrown when supplying the - indent value with a string that is not a valid integer. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "good_list_indentation.md" - ) - supplied_arguments = [ - "--set", - "plugins.md007.indent=$#5", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md007.indent' is not valid: Allowable values are between 2 and 4." - ) - - # 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_md007_good_list_indentation_x(): - """ - Test to make sure this rule does not trigger with a document that - only has the required spaces after the list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "good_list_indentation.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_md007_bad_list_indentation_level_0(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "bad_list_indentation_level_0.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:2: " - + "MD007: Unordered list indentation " - + "[Expected: 0, Actual=1] (ul-indent)" - ) - 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_md007_bad_list_indentation_level_0_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_indentation_level_0.md" - ) as temp_source_path: - original_file_contents = """This is a test +__plugin_disable_md005 = "md005" +__plugin_disable_md027 = "md027" +__plugin_disable_md030 = "md030" + + +configTests = [ + pluginConfigErrorTest( + "invalid_indent", + use_strict_config=True, + set_args=["plugins.md007.indent=bad"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md007.indent' must be of type 'int'.""", + ), + pluginConfigErrorTest( + "invalid_start_indented", + use_strict_config=True, + set_args=["plugins.md007.start_indented=bad"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md007.start_indented' must be of type 'bool'.""", + ), + pluginConfigErrorTest( + "invalid_indent_range", + use_strict_config=True, + set_args=["plugins.md007.indent=$#5"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md007.indent' is not valid: Allowable values are between 2 and 4.""", + ), +] + + +scanTests = [ + pluginRuleTest( + "good_list_indentation_x", + source_file_name=f"{source_path}good_list_indentation.md", + ), + pluginRuleTest( + "bad_list_indentation_level_0", + source_file_name=f"{source_path}bad_list_indentation_level_0.md", + source_file_contents="""This is a test * this is level 1 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """This is a test +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:3:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent)", + fix_expected_file_contents="""This is a test * this is level 1 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_indentation_level_1(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 2 list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "bad_list_indentation_level_1.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:4: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_indentation_level_1_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_indentation_level_1.md" - ) as temp_source_path: - original_file_contents = """This is a test +""", + ), + pluginRuleTest( + "bad_list_indentation_level_1", + source_file_name=f"{source_path}bad_list_indentation_level_1.md", + source_file_contents="""This is a test * this is level 1 * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """This is a test +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:4:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)", + fix_expected_file_contents="""This is a test * this is level 1 * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_indentation_level_2(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 3 list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "bad_list_indentation_level_2.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:6: " - + "MD007: Unordered list indentation " - + "[Expected: 4, Actual=5] (ul-indent)" - ) - 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_md007_bad_list_indentation_level_2_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_indentation_level_2.md" - ) as temp_source_path: - original_file_contents = """This is a test +""", + ), + pluginRuleTest( + "bad_list_indentation_level_2", + source_file_name=f"{source_path}bad_list_indentation_level_2.md", + source_file_contents="""This is a test * this is level 1 * this is level 2 * this is level 3 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """This is a test +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:5:6: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent)", + fix_expected_file_contents="""This is a test * this is level 1 * this is level 2 * this is level 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_good_list_indentation_in_block_quote(): - """ - Test to make sure this rule does not trigger with a document that - only has the required spaces after the list item, but in a block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "good_list_indentation_in_block_quote.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_md007_good_list_indentation_in_double_block_quote(): - """ - Test to make sure this rule does not trigger with a document that - only has the required spaces after the list item, but in a doulbe block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "good_list_indentation_in_double_block_quote.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_md007_good_unordered_list_in_ordered_list(): - """ - Test to make sure this rule does not trigger with a document that - only has the required spaces after the list item, but in an ordered list. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "good_unordered_list_in_ordered_list.md" - ) - supplied_arguments = [ - "--disable-rules", - "md030", - "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_md007_bad_unordered_list_in_ordered_list(): - """ - Test to make sure this rule does trigger with a document that has - an unordered list starting with extra spaces inside of an ordered list. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "bad_unordered_list_in_ordered_list.md" - ) - supplied_arguments = [ - "--disable-rules", - "md030", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:6: " - + "MD007: Unordered list indentation " - + "[Expected: 5, Actual=6] (ul-indent)" - ) - 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_md007_bad_unordered_list_in_ordered_list_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_list_in_ordered_list.md" - ) as temp_source_path: - original_file_contents = """1. ordered list +""", + ), + pluginRuleTest( + "good_list_indentation_in_block_quote", + source_file_name=f"{source_path}good_list_indentation_in_block_quote.md", + ), + pluginRuleTest( + "good_list_indentation_in_double_block_quote", + source_file_name=f"{source_path}good_list_indentation_in_double_block_quote.md", + ), + pluginRuleTest( + "good_unordered_list_in_ordered_list", + source_file_name=f"{source_path}good_unordered_list_in_ordered_list.md", + disable_rules=__plugin_disable_md030, + ), + pluginRuleTest( + "bad_unordered_list_in_ordered_list", + source_file_name=f"{source_path}bad_unordered_list_in_ordered_list.md", + disable_rules=__plugin_disable_md030, + source_file_contents="""1. ordered list + sublist -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023,md030", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. ordered list +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:2:6: MD007: Unordered list indentation [Expected: 5, Actual=6] (ul-indent)", + fix_expected_file_contents="""1. ordered list + sublist -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_level_1_unordered_list_in_ordered_list(): - """ - Test to make sure this rule does trigger with a document that has - two nested unordered lists, the inner one starting with extra spaces, - inside of an ordered list. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_level_1_unordered_list_in_ordered_list.md", - ) - supplied_arguments = [ - "--disable-rules", - "md030", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:8: " - + "MD007: Unordered list indentation " - + "[Expected: 7, Actual=8] (ul-indent)" - ) - 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_md007_bad_level_1_unordered_list_in_ordered_list_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_level_1_unordered_list_in_ordered_list.md" - ) as temp_source_path: - original_file_contents = """1. ordered list +""", + ), + pluginRuleTest( + "bad_level_1_unordered_list_in_ordered_list", + source_file_name=f"{source_path}bad_level_1_unordered_list_in_ordered_list.md", + disable_rules=__plugin_disable_md030, + source_file_contents="""1. ordered list + sublist + sublist -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023,md030", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. ordered list +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:3:8: MD007: Unordered list indentation [Expected: 7, Actual=8] (ul-indent)", + fix_expected_file_contents="""1. ordered list + sublist + sublist -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_good_unordered_list_in_double_ordered_list(): - """ - Test to make sure this rule does not trigger with a document that has - two nested ordered lists with a good unordered list with them that - does not have extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "good_unordered_list_in_double_ordered_list.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_md007_bad_unordered_list_in_double_ordered_list(): - """ - Test to make sure this rule does trigger with a document that has - two nested ordered lists with a bad unordered list with them that - does have extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_unordered_list_in_double_ordered_list.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:8: " - + "MD007: Unordered list indentation " - + "[Expected: 7, Actual=8] (ul-indent)" - ) - 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_md007_bad_unordered_list_in_double_ordered_list_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_list_in_double_ordered_list.md" - ) as temp_source_path: - original_file_contents = """1. ordered list +""", + ), + pluginRuleTest( + "good_unordered_list_in_double_ordered_list", + source_file_name=f"{source_path}good_unordered_list_in_double_ordered_list.md", + ), + pluginRuleTest( + "bad_unordered_list_in_double_ordered_list", + source_file_name=f"{source_path}bad_unordered_list_in_double_ordered_list.md", + source_file_contents="""1. ordered list 1. inner ordered list + sublist -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. ordered list +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:3:8: MD007: Unordered list indentation [Expected: 7, Actual=8] (ul-indent)", + fix_expected_file_contents="""1. ordered list 1. inner ordered list + sublist -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_good_unordered_ordered_unordere_ordered_unordered(): - """ - Test to make sure this rule does not trigger with a document that has - nested ordered lists and unordered lists, with no extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "good_unordered_ordered_unordere_ordered_unordered.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_md007_bad_unordered_bad_ordered_unordered_ordered_unordered(): - """ - Test to make sure this rule does trigger with a document that has - nested ordered lists and unordered lists, with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_unordered_bad_ordered_unordered_ordered_unordered.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:2: " - + "MD007: Unordered list indentation " - + "[Expected: 0, Actual=1] (ul-indent)" - ) - 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_md007_bad_unordered_bad_ordered_unordered_ordered_unordered_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_bad_ordered_unordered_ordered_unordered.md" - ) as temp_source_path: - original_file_contents = """ + level 1 +""", + ), + pluginRuleTest( + "good_unordered_ordered_unordere_ordered_unordered", + source_file_name=f"{source_path}good_unordered_ordered_unordere_ordered_unordered.md", + ), + pluginRuleTest( + "bad_unordered_bad_ordered_unordered_ordered_unordered", + source_file_name=f"{source_path}bad_unordered_bad_ordered_unordered_ordered_unordered.md", + source_file_contents=""" + level 1 1. level 2 + level 3 1. level 4 + level 5 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ level 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent)", + fix_expected_file_contents="""+ level 1 1. level 2 + level 3 1. level 4 + level 5 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_unordered_ordered_unordered_bad_ordered_unordered(): - """ - Test to make sure this rule does trigger with a document that has - nested ordered lists and unordered lists, with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_unordered_ordered_unordered_bad_ordered_unordered.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:7: " - + "MD007: Unordered list indentation " - + "[Expected: 6, Actual=7] (ul-indent)" - ) - 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_md007_bad_unordered_ordered_unordered_bad_ordered_unordered_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_ordered_unordered_bad_ordered_unordered.md" - ) as temp_source_path: - original_file_contents = """+ level 1 +""", + ), + pluginRuleTest( + "bad_unordered_ordered_unordered_bad_ordered_unordered", + source_file_name=f"{source_path}bad_unordered_ordered_unordered_bad_ordered_unordered.md", + source_file_contents="""+ level 1 1. level 2 + level 3 1. level 4 + level 5 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ level 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:3:7: MD007: Unordered list indentation [Expected: 6, Actual=7] (ul-indent)", + fix_expected_file_contents="""+ level 1 1. level 2 + level 3 1. level 4 + level 5 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_unordered_ordered_unordered_ordered_unordered_bad(): - """ - Test to make sure this rule does trigger with a document that has - nested ordered lists and unordered lists, with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_unordered_ordered_unordered_ordered_unordered_bad.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:12: " - + "MD007: Unordered list indentation " - + "[Expected: 11, Actual=12] (ul-indent)" - ) - 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_md007_bad_unordered_ordered_unordered_ordered_unordered_bad_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_ordered_unordered_ordered_unordered_bad.md" - ) as temp_source_path: - original_file_contents = """+ level 1 +""", + ), + pluginRuleTest( + "bad_unordered_ordered_unordered_ordered_unordered_bad", + source_file_name=f"{source_path}bad_unordered_ordered_unordered_ordered_unordered_bad.md", + source_file_contents="""+ level 1 1. level 2 + level 3 1. level 4 + level 5 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """+ level 1 +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:5:12: MD007: Unordered list indentation [Expected: 11, Actual=12] (ul-indent)", + fix_expected_file_contents="""+ level 1 1. level 2 - + level 3 - 1. level 4 - + level 5 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_indentation_in_block_quote_level_0(): - """ - Test to make sure this rule does trigger with a document that has - nested unordered lists within a block quote, with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_list_indentation_in_block_quote_level_0.md", - ) - supplied_arguments = [ - "--disable-rules", - "md027", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:4: " - + "MD007: Unordered list indentation " - + "[Expected: 0, Actual=1] (ul-indent)\n" - + f"{source_path}:4:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)\n" - + f"{source_path}:5:8: " - + "MD007: Unordered list indentation " - + "[Expected: 4, Actual=5] (ul-indent)" - ) - 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_md007_bad_list_indentation_in_block_quote_level_0_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_indentation_in_block_quote_level_0.md" - ) as temp_source_path: - original_file_contents = """This is a test + + level 3 + 1. level 4 + + level 5 +""", + ), + pluginRuleTest( + "bad_list_indentation_in_block_quote_level_0", + source_file_name=f"{source_path}bad_list_indentation_in_block_quote_level_0.md", + disable_rules=__plugin_disable_md027, + source_file_contents="""This is a test > * this is level 1 > * this is level 2 > * this is level 3 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md027", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """This is a test +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:3:4: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent)\n" + + "{temp_source_path}:4:6: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)\n" + + "{temp_source_path}:5:8: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent)" + ), + fix_expected_file_contents="""This is a test > * this is level 1 > * this is level 2 > * this is level 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_in_block_quote_after_text(): - """ - Test to make sure this rule does trigger with a document that has - a bad nested unordered lists after a text block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "bad_list_in_block_quote_after_text.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_in_block_quote_after_text_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_in_block_quote_after_text.md" - ) as temp_source_path: - original_file_contents = """> This is some text +""", + ), + pluginRuleTest( + "bad_list_in_block_quote_after_text", + source_file_name=f"{source_path}bad_list_in_block_quote_after_text.md", + source_file_contents="""> This is some text > > * this is level 1 > * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> This is some text +""", + scan_expected_return_code=1, + scan_expected_output=( + "{temp_source_path}:4:6: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)" + ), + fix_expected_file_contents="""> This is some text > > * this is level 1 > * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_in_block_quote_after_atx_heading(): - """ - Test to make sure this rule does trigger with a document that has - a bad nested unordered lists after an Atx Heading. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_list_in_block_quote_after_atx_heading.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_in_block_quote_after_atx_heading_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_in_block_quote_after_atx_heading.md" - ) as temp_source_path: - original_file_contents = """> # This is some text +""", + ), + pluginRuleTest( + "bad_list_in_block_quote_after_atx_heading", + source_file_name=f"{source_path}bad_list_in_block_quote_after_atx_heading.md", + source_file_contents="""> # This is some text > > * this is level 1 > * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> # This is some text +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:4:6: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)", + fix_expected_file_contents="""> # This is some text > > * this is level 1 > * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_in_block_quote_after_thematic_break(): - """ - Test to make sure this rule does trigger with a document that has - a bad nested unordered lists after a thematic break. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_list_in_block_quote_after_thematic_break.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_in_block_quote_after_thematic_break_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_in_block_quote_after_thematic_break.md" - ) as temp_source_path: - original_file_contents = """> This is some text +""", + ), + pluginRuleTest( + "bad_list_in_block_quote_after_thematic_break", + source_file_name=f"{source_path}bad_list_in_block_quote_after_thematic_break.md", + source_file_contents="""> This is some text > > -------- > > * this is level 1 > * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> This is some text +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:6:6: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)", + fix_expected_file_contents="""> This is some text > > -------- > > * this is level 1 > * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_in_block_quote_after_setext_heading(): - """ - Test to make sure this rule does trigger with a document that has - a bad nested unordered lists after a SetExt Heading. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_list_in_block_quote_after_setext_heading.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_in_block_quote_after_setext_heading_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_in_block_quote_after_setext_heading.md" - ) as temp_source_path: - original_file_contents = """> This is some text +""", + ), + pluginRuleTest( + "bad_list_in_block_quote_after_setext_heading", + source_file_name=f"{source_path}bad_list_in_block_quote_after_setext_heading.md", + source_file_contents="""> This is some text > --------- > > * this is level 1 > * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> This is some text +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:5:6: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)", + fix_expected_file_contents="""> This is some text > --------- > > * this is level 1 > * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_in_block_quote_after_html_block(): - """ - Test to make sure this rule does trigger with a document that has - a bad nested unordered lists after a HTML block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_list_in_block_quote_after_html_block.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_in_block_quote_after_html_block_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_in_block_quote_after_html_block.md" - ) as temp_source_path: - original_file_contents = """> > > * this is level 1 > * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> > > * this is level 1 > * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_in_block_quote_after_fenced_block(): - """ - Test to make sure this rule does trigger with a document that has - a bad nested unordered lists after a fenced code block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_list_in_block_quote_after_fenced_block.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_in_block_quote_after_fenced_block_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_in_block_quote_after_fenced_block.md" - ) as temp_source_path: - original_file_contents = """> ```fenced +""", + ), + pluginRuleTest( + "bad_list_in_block_quote_after_fenced_block", + source_file_name=f"{source_path}bad_list_in_block_quote_after_fenced_block.md", + source_file_contents="""> ```fenced > This is a comment > ``` > > * this is level 1 > * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> ```fenced +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:6:6: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)", + fix_expected_file_contents="""> ```fenced > This is a comment > ``` > > * this is level 1 > * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_in_block_quote_after_indented_block(): - """ - Test to make sure this rule does trigger with a document that has - a bad nested unordered lists after an indented code block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_list_in_block_quote_after_indented_block.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_in_block_quote_after_indented_block_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_in_block_quote_after_indented_block.md" - ) as temp_source_path: - original_file_contents = """> This is a comment +""", + ), + pluginRuleTest( + "bad_list_in_block_quote_after_indented_block", + source_file_name=f"{source_path}bad_list_in_block_quote_after_indented_block.md", + source_file_contents="""> This is a comment > > * this is level 1 > * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> This is a comment +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:4:6: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)", + fix_expected_file_contents="""> This is a comment > > * this is level 1 > * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_in_block_quote_after_link_reference_definition(): - """ - Test to make sure this rule does trigger with a document that has - a bad nested unordered lists after a link reference definition. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_list_in_block_quote_after_link_reference_definition.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_in_block_quote_after_link_reference_definition_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_in_block_quote_after_link_reference_definition.md" - ) as temp_source_path: - original_file_contents = """> [link]: /url +""", + ), + pluginRuleTest( + "bad_list_in_block_quote_after_link_reference_definition", + source_file_name=f"{source_path}bad_list_in_block_quote_after_link_reference_definition.md", + source_file_contents="""> [link]: /url > > * this is level 1 > * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> [link]: /url +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:4:6: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)", + fix_expected_file_contents="""> [link]: /url > > * this is level 1 > * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_bad_list_in_block_quote_after_other_list(): - """ - Test to make sure this rule does trigger with a document that has - a bad nested unordered lists after another list - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md007", - "bad_list_in_block_quote_after_other_list.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:6: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)" - ) - 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_md007_bad_list_in_block_quote_after_other_list_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_list_in_block_quote_after_other_list.md" - ) as temp_source_path: - original_file_contents = """> 1. This is another list. +""", + ), + pluginRuleTest( + "bad_list_in_block_quote_after_other_list", + source_file_name=f"{source_path}bad_list_in_block_quote_after_other_list.md", + source_file_contents="""> 1. This is another list. > > * this is level 1 > * this is level 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> 1. This is another list. +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:4:6: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent)", + fix_expected_file_contents="""> 1. This is another list. > > * this is level 1 > * this is level 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_good_unordered_list_elements(): - """ - Test to make sure this rule does not trigger with a document that has - many nested unordered lists, each one properly indented. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "good_unordered_list_elements.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_md007_bad_unordered_list_elements(): - """ - Test to make sure this rule does trigger with a document that has - many nested unordered lists, most of them improperly indented. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "bad_unordered_list_elements.md" - ) - supplied_arguments = [ - "--disable-rules", - "md005", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:2: " - + "MD007: Unordered list indentation " - + "[Expected: 0, Actual=1] (ul-indent)\n" - + f"{source_path}:4:2: " - + "MD007: Unordered list indentation " - + "[Expected: 0, Actual=1] (ul-indent)\n" - + f"{source_path}:5:4: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)\n" - + f"{source_path}:6:4: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)\n" - + f"{source_path}:7:7: " - + "MD007: Unordered list indentation " - + "[Expected: 4, Actual=6] (ul-indent)\n" - + f"{source_path}:8:4: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=3] (ul-indent)\n" - + f"{source_path}:9:5: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=4] (ul-indent)\n" - + f"{source_path}:10:5: " - + "MD007: Unordered list indentation " - + "[Expected: 2, Actual=4] (ul-indent)" - ) - 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_md007_bad_unordered_list_elements_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_unordered_list_elements.md" - ) as temp_source_path: - original_file_contents = """This is a test +""", + ), + pluginRuleTest( + "good_unordered_list_elements", + source_file_name=f"{source_path}good_unordered_list_elements.md", + ), + pluginRuleTest( + "bad_unordered_list_elements", + source_file_name=f"{source_path}bad_unordered_list_elements.md", + disable_rules=__plugin_disable_md005, + source_file_contents="""This is a test * this is level 1 * this is also level 1 @@ -2048,22 +419,18 @@ def test_md007_bad_unordered_list_elements_fix(): * this is also level 2 * this is also level 2 * this is also level 1 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023,md005", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """This is a test +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:4:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:5:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent) +{temp_source_path}:6:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent) +{temp_source_path}:7:7: MD007: Unordered list indentation [Expected: 4, Actual=6] (ul-indent) +{temp_source_path}:8:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent) +{temp_source_path}:9:5: MD007: Unordered list indentation [Expected: 2, Actual=4] (ul-indent) +{temp_source_path}:10:5: MD007: Unordered list indentation [Expected: 2, Actual=4] (ul-indent) +""", + fix_expected_file_contents="""This is a test * this is level 1 * this is also level 1 @@ -2074,160 +441,164 @@ def test_md007_bad_unordered_list_elements_fix(): * this is also level 2 * this is also level 2 * this is also level 1 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md007_good_list_indentation_by_four(): - """ - Test to make sure this rule does not trigger with a document that has - each list indented by 4, but configuration to support it. - - This function shadows - test_api_config_with_good_integer_property - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "good_list_indentation_by_four.md" - ) - supplied_arguments = [ - "--set", - "plugins.md007.indent=$#4", - "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_md007_good_list_indentation_with_start(): - """ - Test to make sure this rule does not trigger with a document that has - the level 1 list indented, due to configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md007", "good_list_indentation_with_start.md" - ) - supplied_arguments = [ - "--set", - "plugins.md007.start_indented=$!True", - "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_md007_issue_301(): - """ - Test to make sure that the reported issue 301 does not happen. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join("test", "resources", "rules", "md007", "issue-301.md") - supplied_arguments = [ - "--set", - "plugins.md007.indent=$#4", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = f"{source_path}:7:5: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent)" - 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_md007_issue_301_fix(): - """ - Test to make sure this rule does trigger with a document that - has the extra spaces after the level 1 list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "issue-301.md") as temp_source_path: - original_file_contents = """# Demo markdown +""", + ), + pluginRuleTest( + "good_list_indentation_by_four", + source_file_name=f"{source_path}good_list_indentation_by_four.md", + set_args=["plugins.md007.indent=$#4"], + ), + pluginRuleTest( + "good_list_indentation_with_start", + source_file_name=f"{source_path}good_list_indentation_with_start.md", + set_args=["plugins.md007.start_indented=$!True"], + ), + pluginRuleTest( + "issue_301", + source_file_name=f"{source_path}issue-301.md", + set_args=["plugins.md007.indent=$#4"], + source_file_contents="""# Demo markdown - Item - Sub item 1. Ordered item - Sub unordered item -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """# Demo markdown +""", + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:7:5: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent)", + fix_expected_file_contents="""# Demo markdown - Item - - Sub item + - Sub item 1. Ordered item - Sub unordered item -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +""", + ), + pluginRuleTest( + "mix_md007_md004", + source_file_contents=""" + first + * second + - third + * first + - second + + third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:2:4: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: asterisk] (ul-style) +{temp_source_path}:2:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent) +{temp_source_path}:3:6: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +{temp_source_path}:3:6: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent) +{temp_source_path}:4:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:5:4: MD004: Inconsistent Unordered List Start style [Expected: plus; Actual: dash] (ul-style) +{temp_source_path}:5:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent) +{temp_source_path}:6:6: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent) +""", + fix_expected_file_contents="""+ first + + second + + third ++ first + + second + + third +""", + ), + pluginRuleTest( + "mix_md007_md005", + source_file_contents=""" + first + + second + + third ++ first + + second + + third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:2:4: MD007: Unordered list indentation [Expected: 2, Actual=3] (ul-indent) +{temp_source_path}:3:6: MD007: Unordered list indentation [Expected: 4, Actual=5] (ul-indent) +{temp_source_path}:4:1: MD005: Inconsistent indentation for list items at the same level [Expected: 1; Actual: 0] (list-indent) +{temp_source_path}:5:3: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 2] (list-indent) +{temp_source_path}:6:5: MD005: Inconsistent indentation for list items at the same level [Expected: 5; Actual: 4] (list-indent) +""", + fix_expected_file_contents="""+ first + + second + + third ++ first + + second + + third +""", + ), + pluginRuleTest( + "mix_md007_md027", + source_file_contents="""> + first +> + second +> + third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:1:4: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:2:7: MD007: Unordered list indentation [Expected: 2, Actual=4] (ul-indent) +{temp_source_path}:3:9: MD007: Unordered list indentation [Expected: 4, Actual=6] (ul-indent) +""", + fix_expected_file_contents="""> + first +> + second +> + third +""", + ), + pluginRuleTest( + "mix_md007_md030", + source_file_contents=""" * First + first paragraph + + * Second + + second paragraph + * Third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:1:2: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:4:5: MD007: Unordered list indentation [Expected: 2, Actual=4] (ul-indent) +{temp_source_path}:4:5: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:7:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:7:2: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First + first paragraph + + * Second + + second paragraph +* Third +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md007_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md007") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md007_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) + + +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md007_config(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_configuration_test(test, f"{source_path}good_list_indentation.md") diff --git a/test/rules/test_md009.py b/test/rules/test_md009.py index e0511439f..72dc76943 100644 --- a/test/rules/test_md009.py +++ b/test/rules/test_md009.py @@ -2,832 +2,396 @@ Module to provide tests related to the MD009 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import ( - assert_file_is_as_expected, - copy_to_temp_file, - read_contents_of_text_file, +from test.rules.utils import ( + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, ) import pytest -from pymarkdown.general.parser_helper import ParserHelper - - -def __generate_expected_contents(temp_source_path: str, break_point: int) -> str: - """ - Given the source file, make any required changes to the file outside of the - plugin. - """ - existing_file_contents = read_contents_of_text_file(temp_source_path) - # print("---\n" + existing_file_contents.replace("\n", "\\n").replace("\t", "\\t") + "\n---") - new_lines = [] - for next_line in existing_file_contents.splitlines(keepends=True): - removed_end_of_line = "" - if next_line and next_line[-1] == "\n": - removed_end_of_line = next_line[-1] - next_line = next_line[:-1] - ( - first_non_whitespace_index, - extracted_whitespace, - ) = ParserHelper.extract_spaces_from_end(next_line) - print("before>:" + next_line + ":<") - if len(extracted_whitespace) < break_point: - next_line = next_line[:first_non_whitespace_index] - else: - next_line = next_line[: first_non_whitespace_index + break_point] - print(" after>:" + next_line + ":<") - next_line += removed_end_of_line - - new_lines.append(next_line) - expected_file_contents = "".join(new_lines) - # print("---\n" + expected_file_contents.replace("\n", "\\n").replace("\t", "\\t") + "\n---") - return expected_file_contents - - -def generate_md009_expected_contents(temp_source_path: str, break_point: int) -> str: - return __generate_expected_contents(temp_source_path, break_point) - - -@pytest.mark.rules -def test_md009_bad_paragraph_increasing_extra(): - """ - Test to make sure this rule does trigger with a document that - has increasing amounts of trailing spaces at the end of lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "bad_paragraph_increasing_extra.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:18: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:3:20: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 3] (no-trailing-spaces)" - ) - 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_md009_bad_paragraph_increasing_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - has increasing amounts of trailing spaces at the end of lines. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "bad_paragraph_increasing_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 2) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_bad_paragraph_increasing_extra_with_config_br_spaces_3(): - """ - Test to make sure this rule does trigger with a document that - has increasing amounts trailing spaces at the end of lines, and - configuration set to 3. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "bad_paragraph_increasing_extra.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.br_spaces=$#3", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:18: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 3; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:2:19: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 3; Actual: 2] (no-trailing-spaces)\n" - + f"{source_path}:4:17: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 3; Actual: 2] (no-trailing-spaces)" - ) - 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_md009_bad_paragraph_increasing_extra_with_config_br_spaces_3_fix(): - """ - Test to make sure this rule does trigger with a document that - has increasing amounts trailing spaces at the end of lines, and - configuration set to 3. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "bad_paragraph_increasing_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md009.br_spaces=$#3", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 3) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_bad_paragraph_increasing_extra_with_config_br_spaces_0(): - """ - Test to make sure this rule does trigger with a document that - has increasing amounts trailing spaces at the end of lines, and - configuration set to 0. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "bad_paragraph_increasing_extra.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.br_spaces=$#0", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:18: " - + "MD009: Trailing spaces " - + "[Expected: 0; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:2:19: " - + "MD009: Trailing spaces " - + "[Expected: 0; Actual: 2] (no-trailing-spaces)\n" - + f"{source_path}:3:20: " - + "MD009: Trailing spaces " - + "[Expected: 0; Actual: 3] (no-trailing-spaces)\n" - + f"{source_path}:4:17: " - + "MD009: Trailing spaces " - + "[Expected: 0; Actual: 2] (no-trailing-spaces)" - ) - 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_md009_bad_paragraph_increasing_extra_with_config_br_spaces_0_fix(): - """ - Test to make sure this rule does trigger with a document that - has increasing amounts trailing spaces at the end of lines, and - configuration set to 0. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "bad_paragraph_increasing_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md009.br_spaces=$#0", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 0) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_bad_paragraph_increasing_extra_with_config_strict(): - """ - Test to make sure this rule does trigger with a document that - has increasing amounts trailing spaces at the end of lines, and - configuration set to strict. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "bad_paragraph_increasing_extra.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.strict=$!True", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:18: " - + "MD009: Trailing spaces " - + "[Expected: 0; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:2:19: " - + "MD009: Trailing spaces " - + "[Expected: 0; Actual: 2] (no-trailing-spaces)\n" - + f"{source_path}:3:20: " - + "MD009: Trailing spaces " - + "[Expected: 0; Actual: 3] (no-trailing-spaces)\n" - + f"{source_path}:4:17: " - + "MD009: Trailing spaces " - + "[Expected: 0; Actual: 2] (no-trailing-spaces)" - ) - 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_md009_bad_paragraph_increasing_extra_with_config_strict_fix(): - """ - Test to make sure this rule does trigger with a document that - has increasing amounts trailing spaces at the end of lines, and - configuration set to strict. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "bad_paragraph_increasing_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "--set", +source_path = os.path.join("test", "resources", "rules", "md009") + os.sep + +__plugin_disable_md012 = "md012" +__plugin_disable_md023 = "md023" +__plugin_disable_md033 = "md033" + +configTests = [ + pluginConfigErrorTest( + "invalid_br_spaces", + use_strict_config=True, + set_args=["plugins.md009.br_spaces=not-integer"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md009.br_spaces' must be of type 'int'.""", + ), + pluginConfigErrorTest( + "br_spaces_range", + use_strict_config=True, + set_args=["plugins.md009.br_spaces=$#-1"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md009.br_spaces' is not valid: Allowable values are greater than or equal to 0.""", + ), + pluginConfigErrorTest( + "strict_not_boolean", + use_strict_config=True, + set_args=["plugins.md009.strict=not-boolean"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md009.strict' must be of type 'bool'.""", + ), + pluginConfigErrorTest( + "list_item_empty_lines_not_boolean", + use_strict_config=True, + set_args=["plugins.md009.list_item_empty_lines=not-boolean"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md009.list_item_empty_lines' must be of type 'bool'.""", + ), +] + +scanTests = [ + pluginRuleTest( + "good_paragraph_no_extra", + source_file_name=f"{source_path}good_paragraph_no_extra.md", + ), + pluginRuleTest( + "good_indented_code_block_with_extra", + source_file_name=f"{source_path}good_indented_code_block_with_extra.md", + ), + pluginRuleTest( + "good_fenced_code_block_with_extra", + source_file_name=f"{source_path}good_fenced_code_block_with_extra.md", + ), + pluginRuleTest( + "unordered_list_item_empty_lines", + source_file_name=f"{source_path}good_unordered_list_item_empty_lines.md", + ), + pluginRuleTest( + "unordered_list_item_empty_lines_with_config_strict", + source_file_name=f"{source_path}good_unordered_list_item_empty_lines.md", + set_args=["plugins.md009.strict=$!True"], + use_strict_config=True, + source_file_contents="""- list item text +\a\a + list item text +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:2:1: MD009: Trailing spaces [Expected: 0; Actual: 2] (no-trailing-spaces)", + fix_expected_file_contents="""- list item text +\a\a + list item text +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "good_unordered_list_item_empty_lines_with_config_strict_and_list_empty", + source_file_name=f"{source_path}good_unordered_list_item_empty_lines.md", + set_args=[ "plugins.md009.strict=$!True", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 2) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_bad_atx_heading_with_extra(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end of an Atx Heading element. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "bad_atx_heading_with_extra.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:32: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)" + "plugins.md009.list_item_empty_lines=$!True", + ], + use_strict_config=True, + ), + pluginRuleTest( + "good_ordered_list_item_empty_lines_with_list_empty", + source_file_name=f"{source_path}good_unordered_list_item_empty_lines.md", + set_args=["plugins.md009.list_item_empty_lines=$!True"], + use_strict_config=True, + ), + pluginRuleTest( + "bad_paragraph_increasing_extra", + source_file_name=f"{source_path}bad_paragraph_increasing_extra.md", + source_file_contents="""this is some text\a +each line has some\a\a +extra spaces at the\a\a\a +end of the line.\a\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:18: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:3:20: MD009: Trailing spaces [Expected: 0 or 2; Actual: 3] (no-trailing-spaces)""", + fix_expected_file_contents="""this is some text +each line has some\a\a +extra spaces at the\a\a +end of the line.\a\a +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "bad_paragraph_increasing_extra_with_config_br_spaces_3", + source_file_name=f"{source_path}bad_paragraph_increasing_extra.md", + use_strict_config=True, + set_args=["plugins.md009.br_spaces=$#3"], + source_file_contents="""this is some text\a +each line has some\a\a +extra spaces at the\a\a\a +end of the line.\a\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:18: MD009: Trailing spaces [Expected: 0 or 3; Actual: 1] (no-trailing-spaces) +{temp_source_path}:2:19: MD009: Trailing spaces [Expected: 0 or 3; Actual: 2] (no-trailing-spaces) +{temp_source_path}:4:17: MD009: Trailing spaces [Expected: 0 or 3; Actual: 2] (no-trailing-spaces) +""", + fix_expected_file_contents="""this is some text +each line has some +extra spaces at the\a\a\a +end of the line. +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "bad_paragraph_increasing_extra_with_config_br_spaces_0", + source_file_name=f"{source_path}bad_paragraph_increasing_extra.md", + use_strict_config=True, + set_args=["plugins.md009.br_spaces=$#0"], + source_file_contents="""this is some text\a +each line has some\a\a +extra spaces at the\a\a\a +end of the line.\a\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:18: MD009: Trailing spaces [Expected: 0; Actual: 1] (no-trailing-spaces) +{temp_source_path}:2:19: MD009: Trailing spaces [Expected: 0; Actual: 2] (no-trailing-spaces) +{temp_source_path}:3:20: MD009: Trailing spaces [Expected: 0; Actual: 3] (no-trailing-spaces) +{temp_source_path}:4:17: MD009: Trailing spaces [Expected: 0; Actual: 2] (no-trailing-spaces) +""", + fix_expected_file_contents="""this is some text +each line has some +extra spaces at the +end of the line. +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "bad_paragraph_increasing_extra_with_config_strict", + source_file_name=f"{source_path}bad_paragraph_increasing_extra.md", + use_strict_config=True, + set_args=["plugins.md009.strict=$!True"], + source_file_contents="""this is some text\a +each line has some\a\a +extra spaces at the\a\a\a +end of the line.\a\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:18: MD009: Trailing spaces [Expected: 0; Actual: 1] (no-trailing-spaces) +{temp_source_path}:2:19: MD009: Trailing spaces [Expected: 0; Actual: 2] (no-trailing-spaces) +{temp_source_path}:3:20: MD009: Trailing spaces [Expected: 0; Actual: 3] (no-trailing-spaces) +{temp_source_path}:4:17: MD009: Trailing spaces [Expected: 0; Actual: 2] (no-trailing-spaces) +""", + fix_expected_file_contents="""this is some text +each line has some\a\a +extra spaces at the\a\a +end of the line.\a\a +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "bad_atx_heading_with_extra", + source_file_name=f"{source_path}bad_atx_heading_with_extra.md", + source_file_contents="""# A Heading with trailing space\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:32: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces)", + fix_expected_file_contents="""# A Heading with trailing space +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "bad_setext_heading_with_extra", + source_file_name=f"{source_path}bad_setext_heading_with_extra.md", + source_file_contents="""A Heading with trailing space\a +on more than one line\a +---------------------\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:30: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:2:22: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:3:22: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +""", + fix_expected_file_contents="""A Heading with trailing space +on more than one line +--------------------- +""", + ), + pluginRuleTest( + "bad_theamtic_break_with_extra", + source_file_name=f"{source_path}bad_theamtic_break_with_extra.md", + source_file_contents="""----------\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:1:11: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces)", + fix_expected_file_contents="""---------- +""", + ), + pluginRuleTest( + "bad_html_block_with_extra", + source_file_name=f"{source_path}bad_html_block_with_extra.md", + disable_rules=__plugin_disable_md033, + source_file_contents=""" + +\a\a +\a\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:5: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:3:3: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:4:2: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:5:5: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:6:6: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +""", + fix_expected_file_contents=""" + +\a\a +\a\a +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "bad_link_reference_definition_with_extra", + source_file_name=f"{source_path}bad_link_reference_definition_with_extra.md", + source_file_contents="""[abc](\a + /url\a + "title"\a ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:7: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:2:9: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:3:12: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +""", + fix_expected_file_contents="""[abc]( + /url + "title" ) - - -@pytest.mark.rules -def test_md009_bad_atx_heading_with_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end of an Atx Heading element. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "bad_atx_heading_with_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 2) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_bad_setext_heading_with_extra(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end of a SetExt Heading element. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "bad_setext_heading_with_extra.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:30: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:2:22: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:3:22: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)" - ) - 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_md009_bad_setext_heading_with_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end of a SetExt Heading element. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "bad_setext_heading_with_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 2) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_bad_theamtic_break_with_extra(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end of a Thematic break element. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "bad_theamtic_break_with_extra.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:11: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)" - ) - 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_md009_bad_theamtic_break_with_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end of a Thematic break element. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "bad_theamtic_break_with_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 2) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_bad_html_block_with_extra(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces for text within a HTML block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "bad_html_block_with_extra.md" - ) - supplied_arguments = [ - "--disable-rules", - "md033", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:5: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:3:3: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:4:2: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:5:5: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:6:6: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)" - ) - 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_md009_bad_html_block_with_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces for text within a HTML block. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "bad_html_block_with_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md033", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 2) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_bad_link_reference_definition_with_extra(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces within a Link Reference Definition. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md009", - "bad_link_reference_definition_with_extra.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:7: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:2:9: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:3:12: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)" - ) - 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_md009_bad_link_reference_definition_with_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces within a Link Reference Definition. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md009", - "bad_link_reference_definition_with_extra.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 2) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_bad_blank_lines_with_extra(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end various blank lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "bad_blank_lines_with_extra.md" - ) - supplied_arguments = [ - "--disable-rules", - "md012", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 1] (no-trailing-spaces)\n" - + f"{source_path}:3:1: " - + "MD009: Trailing spaces " - + "[Expected: 0 or 2; Actual: 3] (no-trailing-spaces)" - ) - 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_md009_bad_blank_lines_with_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end various blank lines. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "bad_blank_lines_with_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md012", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = __generate_expected_contents(temp_source_path, 2) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +""", + ), + pluginRuleTest( + "bad_blank_lines_with_extra", + source_file_name=f"{source_path}bad_blank_lines_with_extra.md", + disable_rules=__plugin_disable_md012, + source_file_contents="""\a +\a\a +\a\a\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:3:1: MD009: Trailing spaces [Expected: 0 or 2; Actual: 3] (no-trailing-spaces) +""", + fix_expected_file_contents=""" +\a\a +\a\a +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "mix_md009_md023", + source_file_contents=""" ## Heading 2\a\a\a + +Some more text +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:1:15: MD009: Trailing spaces [Expected: 0 or 2; Actual: 3] (no-trailing-spaces) +""", + fix_expected_file_contents="""## Heading 2\a\a + +Some more text +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "mix_md009_md027", + disable_rules=__plugin_disable_md023, + source_file_contents="""> # Header 1\a +> +> ## Header 2\a\a\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:1:14: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:3:15: MD009: Trailing spaces [Expected: 0 or 2; Actual: 3] (no-trailing-spaces) +""", + fix_expected_file_contents="""> # Header 1 +> +> ## Header 2\a\a +""".replace( + "\a", " " + ), + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md009_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md009") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md009_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) + + +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md009_config(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_configuration_test(test, f"{source_path}good_paragraph_no_extra.md") diff --git a/test/rules/test_md009_config.py b/test/rules/test_md009_config.py deleted file mode 100644 index 6b97545dc..000000000 --- a/test/rules/test_md009_config.py +++ /dev/null @@ -1,151 +0,0 @@ -""" -Module to provide tests related to the MD009 rule. -""" -import os -from test.markdown_scanner import MarkdownScanner - -import pytest - - -@pytest.mark.rules -def test_md009_bad_configuration_br_spaces(): - """ - Test to verify that a configuration error is thrown when supplying the - br_spaces value with a string that is not an integer. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_paragraph_no_extra.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.br_spaces=not-integer", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md009.br_spaces' must be of type 'int'." - ) - - # 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_md009_bad_configuration_br_spaces_invalid(): - """ - Test to verify that a configuration error is thrown when supplying the - br_spaces value is not an integer in the proper range. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_paragraph_no_extra.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.br_spaces=$#-1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md009.br_spaces' is not valid: Allowable values are greater than or equal to 0." - ) - - # 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_md009_bad_configuration_strict(): - """ - Test to verify that a configuration error is thrown when supplying the - strict value with a string that is not a boolean. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_paragraph_no_extra.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.strict=not-boolean", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md009.strict' must be of type 'bool'." - ) - - # 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_md009_bad_configuration_list_item_empty_lines(): - """ - Test to verify that a configuration error is thrown when supplying the - list_item_empty_lines value with a string that is not a boolean. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_paragraph_no_extra.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.list_item_empty_lines=not-boolean", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md009.list_item_empty_lines' must be of type 'bool'." - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) diff --git a/test/rules/test_md009_good.py b/test/rules/test_md009_good.py deleted file mode 100644 index 301efb21a..000000000 --- a/test/rules/test_md009_good.py +++ /dev/null @@ -1,514 +0,0 @@ -""" -Module to provide tests related to the MD009 rule. -""" -import os -from test.markdown_scanner import MarkdownScanner -from test.rules.test_md009 import generate_md009_expected_contents -from test.utils import assert_file_is_as_expected, copy_to_temp_file - -import pytest - - -@pytest.mark.rules -def test_md009_good_paragraph_no_extra(): - """ - Test to make sure this rule does not trigger with a document that - has no trailing spaces at the end of lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_paragraph_no_extra.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_md009_good_paragraph_no_extra_fix(): - """ - Test to make sure this rule does not trigger with a document that - has no trailing spaces at the end of lines. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md009", "good_paragraph_no_extra.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_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_md009_good_indented_code_block_with_extra(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces inside of an indented code block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_indented_code_block_with_extra.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_md009_good_indented_code_block_with_extra_fix(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces inside of an indented code block. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md009", - "good_indented_code_block_with_extra.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_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_md009_good_fenced_code_block_with_extra(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces inside of a fenced code block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_fenced_code_block_with_extra.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_md009_good_fenced_code_block_with_extra_fix(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces inside of a fenced code block. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md009", - "good_fenced_code_block_with_extra.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_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_md009_good_unordered_list_item_empty_lines(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces at the end of a blank line within a list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_unordered_list_item_empty_lines.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_md009_good_unordered_list_item_empty_lines_fix(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces at the end of a blank line within a list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md009", - "good_unordered_list_item_empty_lines.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_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_md009_good_unordered_list_item_empty_lines_with_config_strict(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end of a blank line within a list item, - but with strict configuration enabled. - - This function is shadowed by - test_markdown_return_code_default_scan_triggered_at_least_once. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_unordered_list_item_empty_lines.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.strict=$!True", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD009: Trailing spaces " - + "[Expected: 0; Actual: 2] (no-trailing-spaces)" - ) - 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_md009_good_unordered_list_item_empty_lines_with_config_strict_fix(): - """ - Test to make sure this rule does trigger with a document that - has trailing spaces at the end of a blank line within a list item, - but with strict configuration enabled. - - This function is shadowed by - test_markdown_return_code_default_fixed_at_least_one_file. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md009", - "good_unordered_list_item_empty_lines.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md009.strict=$!True", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = generate_md009_expected_contents(temp_source_path, 2) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md009_good_unordered_list_item_empty_lines_with_config_strict_and_list_empty(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces at the end of a blank line within a list item, - with strict and list item empty lines configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_unordered_list_item_empty_lines.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.strict=$!True", - "--set", - "plugins.md009.list_item_empty_lines=$!True", - "--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_md009_good_unordered_list_item_empty_lines_with_config_strict_and_list_empty_fix(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces at the end of a blank line within a list item, - with strict and list item empty lines configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md009", - "good_unordered_list_item_empty_lines.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md009.strict=$!True", - "--set", - "plugins.md009.list_item_empty_lines=$!True", - "--strict-config", - "-x-fix", - "scan", - temp_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_md009_good_ordered_list_item_empty_lines_with_list_empty(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces at the end of a blank line within a list item, - with list item empty lines configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md009", "good_unordered_list_item_empty_lines.md" - ) - supplied_arguments = [ - "--set", - "plugins.md009.list_item_empty_lines=$!True", - "--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_md009_good_ordered_list_item_empty_lines_with_list_empty_fix(): - """ - Test to make sure this rule does not trigger with a document that - has trailing spaces at the end of a blank line within a list item, - with list item empty lines configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md009", - "good_unordered_list_item_empty_lines.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md009.list_item_empty_lines=$!True", - "--strict-config", - "-x-fix", - "scan", - temp_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 - ) diff --git a/test/rules/test_md010.py b/test/rules/test_md010.py index 4e34456fd..b9e981f19 100644 --- a/test/rules/test_md010.py +++ b/test/rules/test_md010.py @@ -2,231 +2,105 @@ Module to provide tests related to the MD010 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import ( - assert_file_is_as_expected, - copy_to_temp_file, - read_contents_of_text_file, +from test.rules.utils import ( + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, ) -from typing import Dict import pytest -from pymarkdown.general.tab_helper import TabHelper - - -def generate_expected_contents( - temp_source_path: str, allowed_after_indent_map: Dict[int, int] = None -) -> str: - """ - Given the source file, make any required changes to the file outside of the - plugin. - """ - existing_file_contents = read_contents_of_text_file(temp_source_path) - # print("---\n" + existing_file_contents.replace("\n", "\\n").replace("\t", "\\t") + "\n---") - new_lines = [] - split_lines = existing_file_contents.splitlines(keepends=True) - for next_line_index, next_line in enumerate(split_lines): - if allowed_after_indent_map and next_line_index + 1 in allowed_after_indent_map: - modify_after_index = allowed_after_indent_map[next_line_index + 1] - altered_line = ( - TabHelper.detabify_string(next_line[:modify_after_index]) - + next_line[modify_after_index:] - ) - else: - altered_line = TabHelper.detabify_string(next_line) - new_lines.append(altered_line) - expected_file_contents = "".join(new_lines) - # print("---\n" + expected_file_contents.replace("\n", "\\n").replace("\t", "\\t") + "\n---") - return expected_file_contents - - -@pytest.mark.rules -def test_md010_bad_configuration_code_blocks(): - """ - Test to verify that a configuration error is thrown when supplying the - code_blocks value with a string that is not a boolean. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md004", "good_list_asterisk_single_level.md" - ) - supplied_arguments = [ - "--set", - "plugins.md010.code_blocks=bad", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md010.code_blocks' must be of type 'bool'." - ) - - # 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_md010_good_simple_text_no_tab(): - """ - Test to make sure this rule does not trigger with a document that - contains no tab characters. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md010", "good_simple_text_no_tab.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_md010_bad_simple_text_with_tab(): - """ - Test to make sure this rule does trigger with a document that - contains tab characters. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md010", "bad_simple_text_with_tab.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:11: MD010: " - + "Hard tabs [Column: 11] (no-hard-tabs)\n" - + f"{source_path}:2:11: MD010: " - + "Hard tabs [Column: 11] (no-hard-tabs)\n" - + f"{source_path}:3:11: MD010: " - + "Hard tabs [Column: 11] (no-hard-tabs)\n" - + f"{source_path}:3:22: MD010: " - + "Hard tabs [Column: 22] (no-hard-tabs)\n" - + f"{source_path}:4:2: MD010: " - + "Hard tabs [Column: 2] (no-hard-tabs)\n" - + f"{source_path}:4:7: MD010: " - + "Hard tabs [Column: 7] (no-hard-tabs)\n" - + f"{source_path}:4:12: MD010: " - + "Hard tabs [Column: 12] (no-hard-tabs)" - ) - 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_md010_bad_simple_text_with_tab_fix(): - """ - Test to make sure this rule does trigger with a document that - contains tab characters. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md010", "bad_simple_text_with_tab.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = generate_expected_contents(temp_source_path) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md010_bad_simple_text_with_tab_fix_and_debug(): - """ - Test to make sure this rule does trigger with a document that - contains tab characters. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", "resources", "rules", "md010", "bad_simple_text_with_tab.md" - ) - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md009", - "-x-fix-debug", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = """md010-before:before-tab\\tafter-tab: +source_path = os.path.join("test", "resources", "rules", "md010") + os.sep + +__plugin_disable_md022 = "md022" +__plugin_disable_md030 = "md030" +__plugin_disable_md031_md040 = "md031,md040" +__plugin_disable_md047 = "MD047" + +configTests = [ + pluginConfigErrorTest( + "invalid_code_blocks", + use_strict_config=True, + set_args=["plugins.md010.code_blocks=bad"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md010.code_blocks' must be of type 'bool'.""", + ), +] + +scanTests = [ + pluginRuleTest( + "good_simple_text_no_tab", + source_file_name=f"{source_path}good_simple_text_no_tab.md", + ), + pluginRuleTest( + "bad_simple_text_with_tab", + source_file_name=f"{source_path}bad_simple_text_with_tab.md", + source_file_contents="""before-tab\tafter-tab +before-tab\tafter-tab +before-tab\tafter-tab\tafter-another +a\tbb\tccc\tddd +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:2:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:3:22: MD010: Hard tabs [Column: 22] (no-hard-tabs) +{temp_source_path}:4:2: MD010: Hard tabs [Column: 2] (no-hard-tabs) +{temp_source_path}:4:7: MD010: Hard tabs [Column: 7] (no-hard-tabs) +{temp_source_path}:4:12: MD010: Hard tabs [Column: 12] (no-hard-tabs) +""", + fix_expected_file_contents="""before-tab after-tab +before-tab after-tab +before-tab after-tab after-another +a bb ccc ddd +""", + ), + pluginRuleTest( + "bad_simple_text_with_tab_fix_and_debug", + source_file_name=f"{source_path}bad_simple_text_with_tab.md", + use_fix_debug=True, + source_file_contents="""before-tab\tafter-tab +before-tab\tafter-tab +before-tab\tafter-tab\tafter-another +a\tbb\tccc\tddd +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:2:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:3:22: MD010: Hard tabs [Column: 22] (no-hard-tabs) +{temp_source_path}:4:2: MD010: Hard tabs [Column: 2] (no-hard-tabs) +{temp_source_path}:4:7: MD010: Hard tabs [Column: 7] (no-hard-tabs) +{temp_source_path}:4:12: MD010: Hard tabs [Column: 12] (no-hard-tabs)""", + fix_expected_file_contents="""before-tab after-tab +before-tab after-tab +before-tab after-tab after-another +a bb ccc ddd +""", + fix_expected_output="""md009-before:before-tab\\tafter-tab: +md010-before:before-tab\\tafter-tab: md010-after :before-tab after-tab: md047-before:before-tab after-tab: nl-ltw:before-tab after-tab\\n: +md009-before:before-tab\\tafter-tab: md010-before:before-tab\\tafter-tab: md010-after :before-tab after-tab: md047-before:before-tab after-tab: nl-ltw:before-tab after-tab\\n: +md009-before:before-tab\\tafter-tab\\tafter-another: md010-before:before-tab\\tafter-tab\\tafter-another: md010-after :before-tab after-tab after-another: md047-before:before-tab after-tab after-another: nl-ltw:before-tab after-tab after-another\\n: +md009-before:a\\tbb\\tccc\\tddd: md010-before:a\\tbb\\tccc\\tddd: md010-after :a bb ccc ddd: md047-before:a bb ccc ddd: nl-ltw:a bb ccc ddd\\n: +md009-before:: md010-before:: md047-before:: was_newline_added_at_end_of_file=True @@ -238,170 +112,466 @@ def test_md010_bad_simple_text_with_tab_fix_and_debug(): FixLineRecord(source='next_line', line_number=2, plugin_id='md010') FixLineRecord(source='next_line', line_number=3, plugin_id='md010') FixLineRecord(source='next_line', line_number=4, plugin_id='md010') -Fixed: {path}""".replace( - "{path}", temp_source_path - ) - expected_error = "" - expected_file_contents = generate_expected_contents(temp_source_path) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md010_bad_simple_text_with_tabs_in_code_block_with_end_line(): +Fixed: {temp_source_path}""", + ), + pluginRuleTest( + "bad_simple_text_with_tabs_in_code_block_with_end_line", + source_file_name=f"{source_path}bad_simple_text_with_tabs_in_code_block.md", + source_file_contents="""This is a code block + +```text +code block +``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:5: MD010: Hard tabs [Column: 5] (no-hard-tabs) +""", + fix_expected_file_contents="""This is a code block + +```text +code block +``` +""", + ), + pluginRuleTest( + "bad_simple_text_with_tabs_in_code_block_no_end_line", + source_file_name=f"{source_path}bad_simple_text_with_tabs_in_code_block_no_end_line.md", + disable_rules=__plugin_disable_md047, + source_file_contents="""This is a code block + +```text +code block +```""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:5: MD010: Hard tabs [Column: 5] (no-hard-tabs) +""", + fix_expected_file_contents="""This is a code block + +```text +code block +```""", + ), + pluginRuleTest( + "good_simple_text_with_tabs_in_code_block_turned_off", + source_file_name=f"{source_path}bad_simple_text_with_tabs_in_code_block.md", + use_strict_config=True, + set_args=["plugins.md010.code_blocks=$!false"], + source_file_contents="""This is a code block + +```text +code block +``` +""", + ), + pluginRuleTest( + "bad_in_block_quotes_fall_off_after_fenced_open", + source_file_name=f"{source_path}bad_block_quote_fall_off_after_fenced_open.md", + disable_rules=__plugin_disable_md031_md040, + source_file_contents="""> this is text +> +> ```text abc + this is not a tab in a code block + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs) +{temp_source_path}:4:30: MD010: Hard tabs [Column: 30] (no-hard-tabs) +""", + fix_expected_file_contents="""> this is text +> +> ```text abc + this is not a tab in a code block + ``` +""", + ), + pluginRuleTest( + "bad_in_bad_block_quote_fall_off_after_fenced_open_and_text", + source_file_name=f"{source_path}bad_block_quote_fall_off_after_fenced_open_and_text.md", + disable_rules=__plugin_disable_md031_md040, + source_file_contents="""> this is text +> +> ```text abc +> this is a tab in a code block + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs) +{temp_source_path}:4:26: MD010: Hard tabs [Column: 26] (no-hard-tabs) +""", + fix_expected_file_contents="""> this is text +> +> ```text abc +> this is a tab in a code block + ``` +""", + ), + pluginRuleTest( + "bad_in_bad_block_quote_fall_off_after_fenced_open_and_text_and_close", + source_file_name=f"{source_path}bad_block_quote_fall_off_after_fenced_open_and_text_and_close.md", + source_file_contents="""> this is text +> +> ```text abc +> this is a tab in a code block +> ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs) +{temp_source_path}:4:26: MD010: Hard tabs [Column: 26] (no-hard-tabs) +""", + fix_expected_file_contents="""> this is text +> +> ```text abc +> this is a tab in a code block +> ``` +""", + ), + pluginRuleTest( + "bad_unordered_list_fall_off_after_fenced_open", + source_file_name=f"{source_path}bad_unordered_list_fall_off_after_fenced_open.md", + disable_rules=__plugin_disable_md031_md040, + source_file_contents="""+ this is text + + ```text def ++ this contains a tab + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs) +{temp_source_path}:4:16: MD010: Hard tabs [Column: 16] (no-hard-tabs) +""", + fix_expected_file_contents="""+ this is text + + ```text def ++ this contains a tab + ``` +""", + ), + pluginRuleTest( + "bad_unordered_list_fall_off_after_fenced_open_and_text", + source_file_name=f"{source_path}bad_unordered_list_fall_off_after_fenced_open_and_text.md", + disable_rules=__plugin_disable_md031_md040, + source_file_contents="""+ this is text + + ```text def + this contains a tab ++ ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs) +{temp_source_path}:4:16: MD010: Hard tabs [Column: 16] (no-hard-tabs) +""", + fix_expected_file_contents="""+ this is text + + ```text def + this contains a tab ++ ``` +""", + ), + pluginRuleTest( + "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close", + source_file_name=f"{source_path}bad_unordered_list_fall_off_after_fenced_open_and_text_and_close.md", + source_file_contents="""- this is text + + ```text def + this contains a tab + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs) +{temp_source_path}:4:16: MD010: Hard tabs [Column: 16] (no-hard-tabs) +""", + fix_expected_file_contents="""- this is text + + ```text def + this contains a tab + ``` +""", + ), + pluginRuleTest( + "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_code_blocks_off", + source_file_name=f"{source_path}bad_unordered_list_fall_off_after_fenced_open_and_text_and_close.md", + set_args=["plugins.md010.code_blocks=$!false"], + use_strict_config=True, + source_file_contents="""- this is text + + ```text def + this contains a tab + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs) +""", + fix_expected_file_contents="""- this is text + + ```text def + this contains\ta tab + ``` +""", + ), + pluginRuleTest( + "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent", + source_file_name=f"{source_path}bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent.md", + disable_rules=__plugin_disable_md030, + source_file_contents="""- this is text + + ```text def + this contains a tab + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:12: MD010: Hard tabs [Column: 12] (no-hard-tabs) +{temp_source_path}:4:18: MD010: Hard tabs [Column: 18] (no-hard-tabs) +""", + fix_expected_file_contents="""- this is text + + ```text def + this contains a tab + ``` +""", + ), + pluginRuleTest( + "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent", + source_file_name=f"{source_path}bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent.md", + disable_rules=__plugin_disable_md030, + source_file_contents="""-\tthis is text + +\t```text\tdef +\tthis contains\ta tab +\t``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD010: Hard tabs [Column: 2] (no-hard-tabs) +{temp_source_path}:3:1: MD010: Hard tabs [Column: 1] (no-hard-tabs) +{temp_source_path}:3:12: MD010: Hard tabs [Column: 12] (no-hard-tabs) +{temp_source_path}:4:1: MD010: Hard tabs [Column: 1] (no-hard-tabs) +{temp_source_path}:4:18: MD010: Hard tabs [Column: 18] (no-hard-tabs) +{temp_source_path}:5:1: MD010: Hard tabs [Column: 1] (no-hard-tabs) +""", + fix_expected_file_contents="""- this is text + + ```text def + this contains a tab + ``` +""", + ), + pluginRuleTest( + "bad_ordered_list_fall_off_after_fenced_open", + source_file_name=f"{source_path}bad_ordered_list_fall_off_after_fenced_open.md", + disable_rules=__plugin_disable_md031_md040, + source_file_contents="""1. this is text + + ```text def +1. this contains a tab + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:4:17: MD010: Hard tabs [Column: 17] (no-hard-tabs) +""", + fix_expected_file_contents="""1. this is text + + ```text def +1. this contains a tab + ``` +""", + ), + pluginRuleTest( + "bad_ordered_list_fall_off_after_fenced_open_and_text", + source_file_name=f"{source_path}bad_ordered_list_fall_off_after_fenced_open_and_text.md", + disable_rules=__plugin_disable_md031_md040, + source_file_contents="""1. this is text + + ```text def + this contains a tab +1. ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:4:17: MD010: Hard tabs [Column: 17] (no-hard-tabs) +""", + fix_expected_file_contents="""1. this is text + + ```text def + this contains a tab +1. ``` +""", + ), + pluginRuleTest( + "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close", + source_file_name=f"{source_path}bad_ordered_list_fall_off_after_fenced_open_and_text_and_close.md", + source_file_contents="""1. this is text + + ```text def + this contains a tab + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:4:17: MD010: Hard tabs [Column: 17] (no-hard-tabs) +""", + fix_expected_file_contents="""1. this is text + + ```text def + this contains a tab + ``` +""", + ), + pluginRuleTest( + "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_code_blocks_off", + source_file_name=f"{source_path}bad_ordered_list_fall_off_after_fenced_open_and_text_and_close.md", + use_strict_config=True, + set_args=["plugins.md010.code_blocks=$!false"], + source_file_contents="""1. this is text + + ```text def + this contains a tab + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +""", + fix_expected_file_contents="""1. this is text + + ```text def + this contains a tab + ``` +""", + ), + pluginRuleTest( + "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent", + source_file_name=f"{source_path}bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent.md", + disable_rules=__plugin_disable_md030, + source_file_contents="""1. this is text + + ```text def + this contains a tab + ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:12: MD010: Hard tabs [Column: 12] (no-hard-tabs) +{temp_source_path}:4:18: MD010: Hard tabs [Column: 18] (no-hard-tabs) +""", + fix_expected_file_contents="""1. this is text + + ```text def + this contains a tab + ``` +""", + ), + pluginRuleTest( + "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent", + source_file_name=f"{source_path}bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent.md", + disable_rules=__plugin_disable_md030, + source_file_contents="""1.\tthis is text + +\t```text\tdef +\tthis contains\ta tab +\t``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD010: Hard tabs [Column: 3] (no-hard-tabs) +{temp_source_path}:3:1: MD010: Hard tabs [Column: 1] (no-hard-tabs) +{temp_source_path}:3:12: MD010: Hard tabs [Column: 12] (no-hard-tabs) +{temp_source_path}:4:1: MD010: Hard tabs [Column: 1] (no-hard-tabs) +{temp_source_path}:4:18: MD010: Hard tabs [Column: 18] (no-hard-tabs) +{temp_source_path}:5:1: MD010: Hard tabs [Column: 1] (no-hard-tabs) +""", + fix_expected_file_contents="""1. this is text + + ```text def + this contains a tab + ``` +""", + ), + pluginRuleTest( + "mix_md010_md019", + source_file_contents="""# Heading 1 + +a line of text\twith\ttabs +""", + 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:15: MD010: Hard tabs [Column: 15] (no-hard-tabs) +{temp_source_path}:3:21: MD010: Hard tabs [Column: 21] (no-hard-tabs) +""", + fix_expected_file_contents="""# Heading 1 + +a line of text with tabs +""", + ), + pluginRuleTest( + "mix_md010_md021", + source_file_contents="""# Heading\t1 # +""", + 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}:1:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +""", + fix_expected_file_contents="""# Heading 1 # +""", + ), + pluginRuleTest( + "mix_md010_md030", + source_file_contents="""* # list item\t1 +* ## list\titem 2 + + paragraph +* ## list\titem 3 +""", + disable_rules=__plugin_disable_md022, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:1:15: MD010: Hard tabs [Column: 15] (no-hard-tabs) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +""", + fix_expected_file_contents="""* # list item 1 +* ## list item 2 + + paragraph +* ## list item 3 +""", + ), + pluginRuleTest( + "mix_md010_md047", + source_file_contents="""item\t1""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:5: MD010: Hard tabs [Column: 5] (no-hard-tabs) +{temp_source_path}:1:6: MD047: Each file should end with a single newline character. (single-trailing-newline) +""", + fix_expected_file_contents="""item 1 +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md010_scan(test: pluginRuleTest) -> None: """ - Test to make sure this rule fires when the code block end is followed - by a blank line, or any other token. + Execute a parameterized scan test for plugin md001. """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_simple_text_with_tabs_in_code_block.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = f"{source_path}:4:5: MD010: Hard tabs [Column: 5] (no-hard-tabs)" - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) + execute_scan_test(test, "md010") -@pytest.mark.rules -def test_md010_bad_simple_text_with_tabs_in_code_block_no_end_line(): +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md010_fix(test: pluginRuleTest) -> None: """ - Test to make sure this rule fires when the code block end token is - the "last" token (except for the end of stream token). + Execute a parameterized fix test for plugin md001. """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_simple_text_with_tabs_in_code_block_no_end_line.md", - ) - supplied_arguments = [ - "-d", - "MD041,MD047", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = f"{source_path}:4:5: MD010: Hard tabs [Column: 5] (no-hard-tabs)" - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) + execute_fix_test(test) -@pytest.mark.rules -def test_md010_bad_simple_text_with_tabs_in_code_block_turned_off(): +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md010_config(test: pluginRuleTest) -> None: """ - Test to make sure this rule fires for a tab within a code block, - when the code blocks setting is turned off. + Execute a parameterized fix test for plugin md001. """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_simple_text_with_tabs_in_code_block.md", - ) - supplied_arguments = [ - "--set", - "plugins.md010.code_blocks=$!false", - "--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 + execute_configuration_test( + test, f"{source_path}bad_simple_text_with_tabs_in_code_block.md" ) - - -@pytest.mark.rules -def test_md010_bad_simple_text_with_tabs_in_code_block_turned_off_and_fix(): - """ - Test to make sure this rule fires for a tab within a code block, - when the code blocks setting is turned off. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_simple_text_with_tabs_in_code_block.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md010.code_blocks=$!false", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 0 - expected_output = "" - expected_error = "" - allowed_after_indent_map = {} - allowed_after_indent_map[4] = 0 - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) diff --git a/test/rules/test_md010_block_quote.py b/test/rules/test_md010_block_quote.py deleted file mode 100644 index 992bb2c23..000000000 --- a/test/rules/test_md010_block_quote.py +++ /dev/null @@ -1,175 +0,0 @@ -""" -Module to provide tests related to the MD010 rule. -""" - -import os -from test.markdown_scanner import MarkdownScanner -from test.rules.test_md010 import generate_expected_contents -from test.utils import assert_file_is_as_expected, copy_to_temp_file - -import pytest - - -@pytest.mark.rules -def test_md010_in_block_quotes_fall_off_after_fenced_open(): - """ - Test to make sure this rule fires for a fenced code block start in a block quote - that ends right away. Because it ends before the "text" of the code block, the - text is normal text, and subject to normal rules for tabs. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_block_quote_fall_off_after_fenced_open.md", - ) - supplied_arguments = [ - "-d", - "md031,md041,md040", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs)\n" - + f"{source_path}:4:30: MD010: Hard tabs [Column: 30] (no-hard-tabs)" - ) - 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_md010_in_bad_block_quote_fall_off_after_fenced_open_and_text(): - """ - Test to make sure this rule fires for the open fenced block line which - does contain a tab, but not the code block content, which also contains a tab. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_block_quote_fall_off_after_fenced_open_and_text.md", - ) - supplied_arguments = [ - "-d", - "md031,md041,md040", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs)\n" - + f"{source_path}:4:26: MD010: Hard tabs [Column: 26] (no-hard-tabs)" - ) - 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_md010_in_bad_block_quote_fall_off_after_fenced_open_and_text_and_close(): - """ - Test to make sure this rule fires for the start of the fenced code block, which - contains a tab, but not for the content. This is different than the - test_md010_in_bad_block_quote_fall_off_after_fenced_open_and_text function in - that the fenced code block is closed "nicely", not by the closing of the block - quote it is contained in. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_block_quote_fall_off_after_fenced_open_and_text_and_close.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs)\n" - + f"{source_path}:4:26: MD010: Hard tabs [Column: 26] (no-hard-tabs)" - ) - 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_md010_in_bad_block_quote_fall_off_after_fenced_open_and_text_and_close_and_fix(): - """ - Test to make sure this rule fires for the start of the fenced code block, which - contains a tab, but not for the content. This is different than the - test_md010_in_bad_block_quote_fall_off_after_fenced_open_and_text function in - that the fenced code block is closed "nicely", not by the closing of the block - quote it is contained in. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_block_quote_fall_off_after_fenced_open_and_text_and_close.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - allowed_after_indent_map = {} - # allowed_after_indent_map[4] = 0 - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) diff --git a/test/rules/test_md010_ordered_list.py b/test/rules/test_md010_ordered_list.py deleted file mode 100644 index e9a54b65e..000000000 --- a/test/rules/test_md010_ordered_list.py +++ /dev/null @@ -1,427 +0,0 @@ -""" -Module to provide tests related to the MD010 rule. -""" - -import os -from test.markdown_scanner import MarkdownScanner -from test.rules.test_md010 import generate_expected_contents -from test.utils import assert_file_is_as_expected, copy_to_temp_file - -import pytest - - -@pytest.mark.rules -def test_md010_bad_ordered_list_fall_off_after_fenced_open(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started within an ordered list, but is then closed before - any text can be placed in the code block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open.md", - ) - supplied_arguments = [ - "-d", - "md031,md040,md041", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs)\n" - + f"{source_path}:4:17: MD010: Hard tabs [Column: 17] (no-hard-tabs)" - ) - 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_md010_bad_ordered_list_fall_off_after_fenced_open_and_text(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started within an ordered list and has text in the code - block, but is then closed without using an end code block sequence. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open_and_text.md", - ) - supplied_arguments = [ - "-d", - "md031,md040,md041", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs)\n" - + f"{source_path}:4:17: MD010: Hard tabs [Column: 17] (no-hard-tabs)" - ) - 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_md010_bad_ordered_list_fall_off_after_fenced_open_and_text_and_close(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started, has text, and is properly closed, all within an - ordered list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs)\n" - + f"{source_path}:4:17: MD010: Hard tabs [Column: 17] (no-hard-tabs)" - ) - 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_md010_bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_and_fix(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started, has text, and is properly closed, all within an - ordered list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - allowed_after_indent_map = {} - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md010_bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_code_blocks_off(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started, has text, and is properly closed, all within an - ordered list item, but has code blocks turned off. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close.md", - ) - supplied_arguments = [ - "--set", - "plugins.md010.code_blocks=$!false", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:11: MD010: Hard tabs [Column: 11] (no-hard-tabs)" - ) - 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_md010_bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_code_blocks_off_and_fix(): - """ - Test to make sure this fires properly for a tab in a code block within an - ordered list. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md010.code_blocks=$!false", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - allowed_after_indent_map = {} - allowed_after_indent_map[4] = 0 - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md010_bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent(): - """ - Test to make sure we handle things properly in an ordered list that - uses spaces for the ident. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent.md", - ) - supplied_arguments = [ - "-d", - "md030,md041", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:12: MD010: Hard tabs [Column: 12] (no-hard-tabs)\n" - + f"{source_path}:4:18: MD010: Hard tabs [Column: 18] (no-hard-tabs)" - ) - 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_md010_bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent_and_fix(): - """ - Test to make sure we handle things properly in an ordered list that - uses spaces for the ident. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-d", - "md030,md041", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - allowed_after_indent_map = {} - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md010_bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent(): - """ - Test to make sure we handle things properly in an ordered list that - uses tabs for the ident. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent.md", - ) - supplied_arguments = [ - "-d", - "md030,md041", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:3: MD010: Hard tabs [Column: 3] (no-hard-tabs)\n" - + f"{source_path}:3:1: MD010: Hard tabs [Column: 1] (no-hard-tabs)\n" - + f"{source_path}:3:12: MD010: Hard tabs [Column: 12] (no-hard-tabs)\n" - + f"{source_path}:4:1: MD010: Hard tabs [Column: 1] (no-hard-tabs)\n" - + f"{source_path}:4:18: MD010: Hard tabs [Column: 18] (no-hard-tabs)\n" - + f"{source_path}:5:1: MD010: Hard tabs [Column: 1] (no-hard-tabs)" - ) - 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_md010_bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent_and_fix(): - """ - Test to make sure we handle things properly in an ordered list that - uses tabs for the ident. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_ordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-d", - "md030,md041", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - allowed_after_indent_map = {} - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) diff --git a/test/rules/test_md010_unordered_list.py b/test/rules/test_md010_unordered_list.py deleted file mode 100644 index 063815e00..000000000 --- a/test/rules/test_md010_unordered_list.py +++ /dev/null @@ -1,427 +0,0 @@ -""" -Module to provide tests related to the MD010 rule. -""" - -import os -from test.markdown_scanner import MarkdownScanner -from test.rules.test_md010 import generate_expected_contents -from test.utils import assert_file_is_as_expected, copy_to_temp_file - -import pytest - - -@pytest.mark.rules -def test_md010_bad_unordered_list_fall_off_after_fenced_open(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started within an unordered list, but is then closed before - any text can be placed in the code block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open.md", - ) - supplied_arguments = [ - "-d", - "md031,md040,md041", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs)\n" - + f"{source_path}:4:16: MD010: Hard tabs [Column: 16] (no-hard-tabs)" - ) - 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_md010_bad_unordered_list_fall_off_after_fenced_open_and_text(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started within an unordered list and has text in the code - block, but is then closed without using an end code block sequence. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open_and_text.md", - ) - supplied_arguments = [ - "-d", - "md031,md040,md041", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs)\n" - + f"{source_path}:4:16: MD010: Hard tabs [Column: 16] (no-hard-tabs)" - ) - 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_md010_bad_unordered_list_fall_off_after_fenced_open_and_text_and_close(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started, has text, and is properly closed, all within an - unordered list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs)\n" - + f"{source_path}:4:16: MD010: Hard tabs [Column: 16] (no-hard-tabs)" - ) - 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_md010_bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_and_fix(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started, has text, and is properly closed, all within an - unordered list item. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - allowed_after_indent_map = {} - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md010_bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_code_blocks_off(): - """ - Test to make sure this rule fires properly for a fenced code block - that is started, has text, and is properly closed, all within an - unordered list item, but with code blocks turned off. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close.md", - ) - supplied_arguments = [ - "--set", - "plugins.md010.code_blocks=$!false", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:10: MD010: Hard tabs [Column: 10] (no-hard-tabs)" - ) - 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_md010_bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_code_blocks_off_and_fix(): - """ - Test to make sure this fires properly for a tab in a code block within an - unordered list. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md010.code_blocks=$!false", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - allowed_after_indent_map = {} - allowed_after_indent_map[4] = 0 - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md010_bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent(): - """ - Test to make sure we handle things properly in an unordered list that - uses spaces for the ident. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent.md", - ) - supplied_arguments = [ - "-d", - "md030,md041", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:12: MD010: Hard tabs [Column: 12] (no-hard-tabs)\n" - + f"{source_path}:4:18: MD010: Hard tabs [Column: 18] (no-hard-tabs)" - ) - 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_md010_bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent_and_fix(): - """ - Test to make sure we handle things properly in an unordered list that - uses spaces for the ident. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_space_indent.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-d", - "md030,md041", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - allowed_after_indent_map = {} - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md010_bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent(): - """ - Test to make sure we handle things properly in an unordered list that - uses tabs for the ident. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent.md", - ) - supplied_arguments = [ - "-d", - "md030,md041", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:2: MD010: Hard tabs [Column: 2] (no-hard-tabs)\n" - + f"{source_path}:3:1: MD010: Hard tabs [Column: 1] (no-hard-tabs)\n" - + f"{source_path}:3:12: MD010: Hard tabs [Column: 12] (no-hard-tabs)\n" - + f"{source_path}:4:1: MD010: Hard tabs [Column: 1] (no-hard-tabs)\n" - + f"{source_path}:4:18: MD010: Hard tabs [Column: 18] (no-hard-tabs)\n" - + f"{source_path}:5:1: MD010: Hard tabs [Column: 1] (no-hard-tabs)" - ) - 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_md010_bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent_and_fix(): - """ - Test to make sure we handle things properly in an unordered list that - uses tabs for the ident. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md010", - "bad_unordered_list_fall_off_after_fenced_open_and_text_and_close_with_extra_tab_indent.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-d", - "md030,md041", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - allowed_after_indent_map = {} - expected_file_contents = generate_expected_contents( - temp_source_path, allowed_after_indent_map - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) diff --git a/test/rules/test_md019.py b/test/rules/test_md019.py index af0201982..c33033bec 100644 --- a/test/rules/test_md019.py +++ b/test/rules/test_md019.py @@ -2,8 +2,12 @@ Module to provide tests related to the MD019 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, +) import pytest @@ -11,349 +15,135 @@ source_path = os.path.join("test", "resources", "rules", "md019") + os.sep +__plugin_disable_md010 = "md010" +__plugin_disable_md023 = "md023" -@pytest.mark.rules -def test_md019_good_single_spacing(): - """ - Test to make sure this rule does not trigger with a document that - contains an Atx Heading with a single space before text. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md019", "single_spacing.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_md019_bad_multiple_spacing(): - """ - Test to make sure this rule does not trigger with a document that - contains Atx Headings with multiple spaces before text. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md019", "multiple_spacing.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)\n" - + f"{source_path}:3:1: " - + "MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)\n" - ) - 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_md019_bad_multiple_spacing_fix(): - """ - Test to make sure this rule does not trigger with a document that - contains Atx Headings with multiple spaces before text. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "multiple_spacing.md") as temp_source_path: - original_file_contents = """# Heading 1 +scanTests = [ + pluginRuleTest( + "good_single_spacing", + source_file_name=f"{source_path}single_spacing.md", + ), + pluginRuleTest( + "bad_multiple_spacing", + source_file_name=f"{source_path}multiple_spacing.md", + source_file_contents="""# Heading 1 ## Heading 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """# Heading 1 +""", + 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 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -def test_md019_bad_multiple_spacing_with_inline(): - """ - Test to make sure this rule does not trigger with a document that - contains multiple Atx Headings with multiple spaces before text, - including an inline element in the heading. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md019", "multiple_spacing_with_inline.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)\n" - + f"{source_path}:3:1: " - + "MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)\n" - ) - 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_md019_bad_multiple_spacing_with_inline_fix(): - """ - Test to make sure this rule does not trigger with a document that - contains Atx Headings with multiple spaces before text. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "multiple_spacing_with_inline.md" - ) as temp_source_path: - original_file_contents = """# Heading *number* 1 +""", + ), + pluginRuleTest( + "bad_multiple_spacing_with_inline", + source_file_name=f"{source_path}multiple_spacing_with_inline.md", + source_file_contents="""# Heading *number* 1 ## Heading *number* 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """# Heading *number* 1 +""", + 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 *number* 1 ## Heading *number* 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -def test_md019_bad_multiple_spacing_with_indent(): - """ - Test to make sure this rule does not trigger with a document that - contains multiple Atx Headings with multiple spaces before text, - including indets. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md019", "multiple_spacing_with_indent.md" - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:2: " - + "MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)\n" - + f"{source_path}:3:3: " - + "MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)\n" - ) - 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_md019_bad_multiple_spacing_with_indent_fix(): - """ - Test to make sure this rule does not trigger with a document that - contains Atx Headings with multiple spaces before text. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "multiple_spacing_with_indent.md" - ) as temp_source_path: - original_file_contents = """ # Heading 1 +""", + ), + pluginRuleTest( + "bad_multiple_spacing_with_indent", + source_file_name=f"{source_path}multiple_spacing_with_indent.md", + disable_rules=__plugin_disable_md023, + source_file_contents=""" # Heading 1 ## Heading 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ # Heading 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +{temp_source_path}:3:3: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)""", + fix_expected_file_contents=""" # Heading 1 ## Heading 2 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -def test_md019_bad_single_space_single_tab(): - """ - Test to make sure this rule does trigger with a document that - contains multiple Atx Headings with tabs before text. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md019", "single_space_single_tab.md" - ) - supplied_arguments = [ - "--disable-rules", - "md010", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)\n" - + f"{source_path}:3:1: " - + "MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)" - ) - 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_md019_bad_single_space_single_tab_fix(): - """ - Test to make sure this rule does not trigger with a document that - contains Atx Headings with multiple spaces before text. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "single_space_single_tab.md" - ) as temp_source_path: - original_file_contents = """# \tHeading 1 +""", + ), + pluginRuleTest( + "bad_single_space_single_tab", + source_file_name=f"{source_path}single_space_single_tab.md", + disable_rules=__plugin_disable_md010, + source_file_contents="""# \tHeading 1 ## \tHeading 2 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md010", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """# Heading 1 +""", + 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 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +""", + ), + pluginRuleTest( + "mix_md019_md010", + source_file_contents="""# Heading 1 + +a line of text\twith\ttabs +""", + 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:15: MD010: Hard tabs [Column: 15] (no-hard-tabs) +{temp_source_path}:3:21: MD010: Hard tabs [Column: 21] (no-hard-tabs) +""", + fix_expected_file_contents="""# Heading 1 + +a line of text with tabs +""", + ), + pluginRuleTest( + "mix_md019_md023", + source_file_contents=""" # Heading 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +{temp_source_path}:1:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +""", + fix_expected_file_contents="""# Heading 1 +""", + ), + pluginRuleTest( + "mix_md019_md047", + source_file_contents="""# Heading 1 + +a line of 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) +{temp_source_path}:3:14: MD047: Each file should end with a single newline character. (single-trailing-newline)""", + fix_expected_file_contents="""# Heading 1 + +a line of text +""", + ), +] + +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md019_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md019") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md019_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) diff --git a/test/rules/test_md020.py b/test/rules/test_md020.py index 3a85c61b5..0bd2dcce8 100644 --- a/test/rules/test_md020.py +++ b/test/rules/test_md020.py @@ -225,7 +225,7 @@ def test_md020_bad_missing_start_spacing_in_block_quotes(): ) supplied_arguments = [ "--disable-rules", - "md009", + "md009,md027", "scan", source_path, ] @@ -483,7 +483,7 @@ def test_md020_bad_missing_both_spacing_in_block_quotes(): ) supplied_arguments = [ "--disable-rules", - "md009", + "md009,md027", "scan", source_path, ] diff --git a/test/rules/test_md021.py b/test/rules/test_md021.py index a176087d2..e2b6216a9 100644 --- a/test/rules/test_md021.py +++ b/test/rules/test_md021.py @@ -2,8 +2,12 @@ Module to provide tests related to the MD021 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, +) import pytest @@ -11,417 +15,143 @@ source_path = os.path.join("test", "resources", "rules", "md021") + os.sep +__plugin_disable_md010 = "md010" -@pytest.mark.rules -def test_md021_good_single_spacing(): - """ - Test to make sure this rule does not trigger with a document that - contains an Atx Closed Heading with single spaces at both ends. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md021", "single_spacing.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_md021_bad_multiple_spacing_both(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx Closed Heading with multiple spaces at both ends. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md021", "multiple_spacing.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - + f"{source_path}:3:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - ) - 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_md021_bad_multiple_spacing_both_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "multiple_spacing.md") as temp_source_path: - original_file_contents = """# Heading 1 # +scanTests = [ + pluginRuleTest( + "good_single_spacing", + source_file_name=f"{source_path}single_spacing.md", + ), + pluginRuleTest( + "bad_multiple_spacing_both", + source_file_name=f"{source_path}multiple_spacing.md", + source_file_contents="""# Heading 1 # ## Heading 2 ## -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """# Heading 1 # +""", + 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 ## -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md021_bad_multiple_spacing_left(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx Closed Heading with multiples spaces at the start. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md021", "multiple_spacing_left.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - + f"{source_path}:3:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - ) - 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_md021_bad_multiple_spacing_left_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "multiple_spacing_left.md" - ) as temp_source_path: - original_file_contents = """# Heading 1 # +""", + ), + pluginRuleTest( + "bad_multiple_spacing_left", + source_file_name=f"{source_path}multiple_spacing_left.md", + source_file_contents="""# Heading 1 # ## Heading 2 ## -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """# Heading 1 # +""", + 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 ## -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md021_bad_multiple_spacing_right(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx Closed Heading with multiple spaces at the end. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md021", "multiple_spacing_right.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - + f"{source_path}:3:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - ) - 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_md021_bad_multiple_spacing_right_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "multiple_spacing_right.md" - ) as temp_source_path: - original_file_contents = """# Heading 1 # +""", + ), + pluginRuleTest( + "bad_multiple_spacing_right", + source_file_name=f"{source_path}multiple_spacing_right.md", + source_file_contents="""# Heading 1 # ## Heading 2 ## -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """# Heading 1 # +""", + 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 ## -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - +""", + ), + pluginRuleTest( + "good_multiple_spacing_with_inline", + source_file_name=f"{source_path}multiple_spacing_with_inline.md", + ), + pluginRuleTest( + "bad_multiple_spacing_with_indent", + source_file_name=f"{source_path}multiple_spacing_left.md", + source_file_contents="""# Heading 1 # -@pytest.mark.rules -def test_md021_good_multiple_spacing_with_inline(): - """ - Test to make sure this rule does not trigger with a document that - contains an Atx Closed Heading with inline emphasis. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md021", "multiple_spacing_with_inline.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_md021_good_multiple_spacing_with_indent(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx Closed Heading with multiple spaces at both ends and indents. - """ +## 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 # - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md021", "multiple_spacing_with_indent.md" - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] +## Heading 2 ## +""", + ), + pluginRuleTest( + "bad_single_space_single_tab_before", + source_file_name=f"{source_path}single_space_single_tab_before.md", + disable_rules=__plugin_disable_md010, + source_file_contents="""# \tHeading 1 # + +## \tHeading 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 # - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:2: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - + f"{source_path}:3:3: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - ) - expected_error = "" +## Heading 2 ## +""", + ), + pluginRuleTest( + "bad_single_space_single_tab_after", + source_file_name=f"{source_path}single_space_single_tab_after.md", + disable_rules=__plugin_disable_md010, + source_file_contents="""# Heading 1\t # + +## Heading 2\t ## +""", + 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 # - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) +## Heading 2 ## +""", + ), + pluginRuleTest( + "mix_md021_md010", + source_file_contents="""# Heading\t1 # +""", + 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}:1:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +""", + fix_expected_file_contents="""# Heading 1 # +""", + ), +] - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) -@pytest.mark.rules -def test_md021_good_single_space_single_tab_before(): +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md021_scan(test: pluginRuleTest) -> None: """ - Test to make sure this rule does not trigger with a document that - contains an Atx Closed Heading with tabs at the left end. + Execute a parameterized scan test for plugin md001. """ + execute_scan_test(test, "md021") - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md021", "single_space_single_tab_before.md" - ) - supplied_arguments = [ - "--disable-rules", - "md010", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - + f"{source_path}:3:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)" - ) - 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_md021_good_single_space_single_tab_after(): +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md021_fix(test: pluginRuleTest) -> None: """ - Test to make sure this rule does not trigger with a document that - contains an Atx Closed Heading with tabs at the end. + Execute a parameterized fix test for plugin md001. """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md021", "single_space_single_tab_after.md" - ) - supplied_arguments = [ - "--disable-rules", - "md010", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)\n" - + f"{source_path}:3:1: " - + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - + "(no-multiple-space-closed-atx)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) + execute_fix_test(test) diff --git a/test/rules/test_md023.py b/test/rules/test_md023.py index 40818c93d..4e0909833 100644 --- a/test/rules/test_md023.py +++ b/test/rules/test_md023.py @@ -2,459 +2,114 @@ Module to provide tests related to the MD023 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import ( - assert_file_is_as_expected, - copy_to_temp_file, - create_temporary_configuration_file, +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, ) import pytest source_path = os.path.join("test", "resources", "rules", "md023") + os.sep - -@pytest.mark.rules -def test_md023_good_proper_indent_atx(): - """ - Test to make sure this rule does not trigger with a document that - contains an Atx heading that starts at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "proper_indent_atx.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "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_md023_good_proper_indent_setext(): - """ - Test to make sure this rule does not trigger with a document that - contains a SetExt heading that starts at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "proper_indent_setext.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "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_md023_bad_improper_indent_atx(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "improper_indent_atx.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - ) - 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_md023_bad_improper_indent_atx_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "improper_indent_atx.md") as temp_source_path: - original_file_contents = """Some text +plugin_enable_this_rule = "MD023" + +__plugin_disable_md005_md030_md032 = "MD005,md030,md032" +__plugin_disable_md009 = "md009" +__plugin_disable_md009_md022_md027 = "md009,md022,MD027" +__plugin_disable_md022_md030 = "MD022,md030" +__plugin_disable_md027 = "MD027" + +scanTests = [ + pluginRuleTest( + "good_proper_indent_atx", + source_file_name=f"{source_path}proper_indent_atx.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "good_proper_indent_setext", + source_file_name=f"{source_path}proper_indent_setext.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "bad_improper_indent_atx", + source_file_name=f"{source_path}improper_indent_atx.md", + enable_rules=plugin_enable_this_rule, + source_file_contents="""Some text ## Heading 2 Some more text -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """Some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)""", + fix_expected_file_contents="""Some text ## Heading 2 Some more text -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md023_good_proper_indent_atx_in_list_item(): - """ - Test to make sure this rule does not trigger with a document that - contains an Atx heading that does start at the very left within a list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "proper_indent_atx_in_list_item.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "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_md023_bad_improper_indent_atx_in_list_item(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left in a list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "improper_indent_atx_in_list_item.md" - ) - supplied_arguments = [ - "--disable-rules", - "MD022,md030", - "--enable-rules", - "MD023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:6: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)" - ) - 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_md023_bad_improper_indent_atx_in_list_item_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "improper_indent_atx_in_list_item.md" - ) as temp_source_path: - original_file_contents = """1. Some text +""", + ), + pluginRuleTest( + "good_proper_indent_atx_in_list_item", + source_file_name=f"{source_path}proper_indent_atx_in_list_item.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "bad_improper_indent_atx_in_list_item", + source_file_name=f"{source_path}improper_indent_atx_in_list_item.md", + disable_rules=__plugin_disable_md022_md030, + enable_rules=plugin_enable_this_rule, + source_file_contents="""1. Some text 1. ## Heading 2 ## Heading 2.1 1. Some more text -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "MD022,md030", - "--enable-rules", - "MD023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:6: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +""", + fix_expected_file_contents="""1. Some text 1. ## Heading 2 ## Heading 2.1 1. Some more text -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md023_good_proper_indent_atx_in_block_quote(): - """ - Test to make sure this rule does not trigger with a document that - contains an Atx heading that does start at the very left within a block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "proper_indent_atx_in_block_quote.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "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_md023_bad_improper_indent_atx_in_block_quote(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left in a block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "improper_indent_atx_in_block_quote.md" - ) - supplied_arguments = [ - "--disable-rules", - "MD027", - "--enable-rules", - "MD023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:4: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)" - ) - 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_md023_bad_improper_indent_atx_in_block_quote_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "improper_indent_atx_in_block_quote.md" - ) as temp_source_path: - original_file_contents = """> Some text +""", + ), + pluginRuleTest( + "good_proper_indent_atx_in_block_quote", + source_file_name=f"{source_path}proper_indent_atx_in_block_quote.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "bad_improper_indent_atx_in_block_quote", + source_file_name=f"{source_path}improper_indent_atx_in_block_quote.md", + disable_rules=__plugin_disable_md027, + enable_rules=plugin_enable_this_rule, + source_file_contents="""> Some text > > ## Heading 2 > > Some more text -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "MD027", - "--enable-rules", - "MD023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> Some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:4: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +""", + fix_expected_file_contents="""> Some text > > ## Heading 2 > > Some more text -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md023_bad_improper_indent_setext_x(): - """ - Test to make sure this rule does trigger with a document that - contains a SetExt heading that any part of it does not start at - the very left. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "improper_indent_setext.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:3: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - + f"{source_path}:9:3: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - + f"{source_path}:14:1: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - + f"{source_path}:22:1: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - ) - 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_md023_bad_improper_indent_setext_x_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "improper_indent_setext.md" - ) as temp_source_path: - original_file_contents = """Some text +""", + ), + pluginRuleTest( + "bad_improper_indent_setext_x", + source_file_name=f"{source_path}improper_indent_setext.md", + enable_rules=plugin_enable_this_rule, + source_file_contents="""Some text Heading 2 --------- @@ -476,20 +131,14 @@ def test_md023_bad_improper_indent_setext_x_fix(): Very Long Heading ----------------- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """Some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:9:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:14:1: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:22:1: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +""", + fix_expected_file_contents="""Some text Heading 2 --------- @@ -511,79 +160,14 @@ def test_md023_bad_improper_indent_setext_x_fix(): Very Long Heading ----------------- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md023_bad_improper_indent_setext_in_block_quote(): - """ - Test to make sure this rule does trigger with a document that - contains a SetExt heading that any part of it does not start at - the very left in a block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md023", - "improper_indent_setext_in_block_quote.md", - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "--disable-rules", - "MD027,md022,md009", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:5: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - + f"{source_path}:9:5: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - + f"{source_path}:14:3: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - + f"{source_path}:22:3: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - ) - 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_md023_bad_improper_indent_setext_in_block_quote_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "improper_indent_setext_in_block_quote.md" - ) as temp_source_path: - original_file_contents = """> Some text +""", + ), + pluginRuleTest( + "bad_improper_indent_setext_in_block_quote", + source_file_name=f"{source_path}improper_indent_setext_in_block_quote.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md009_md022_md027, + source_file_contents="""> Some text > > Heading 2 > --------- @@ -609,22 +193,14 @@ def test_md023_bad_improper_indent_setext_in_block_quote_fix(): > Normal Heading > --------- > -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-d", - "md009,md027", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> Some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:5: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:9:5: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:14:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:22:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +""", + fix_expected_file_contents="""> Some text > > Heading 2 > --------- @@ -650,111 +226,25 @@ def test_md023_bad_improper_indent_setext_in_block_quote_fix(): > Normal Heading > --------- > -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md023_good_proper_indent_setext_in_block_quote_no_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """> A Very\a +""", + ), + pluginRuleTest( + "good_proper_indent_setext_in_block_quote", + source_file_contents="""> A Very\a > Long Heading > ----------------- """.replace( - "\a", " " - ) - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--stack-trace", - "-d", - "md009", - "-x-fix", - "scan", - temp_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_md023_bad_improper_indent_setext_in_list_item(): - """ - Test to make sure this rule does trigger with a document that - contains a SetExt heading that any part of it does not start at - the very left in a list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "improper_indent_setext_in_list_item.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "--disable-rules", - "MD005,md030,md032", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:9:6: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - + f"{source_path}:22:3: " - + "MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left)\n" - ) - 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_md023_bad_improper_indent_setext_in_list_item_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an Atx heading that does not start at the very left. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "improper_indent_setext_in_list_item.md" - ) as temp_source_path: - original_file_contents = """- Some text + "\a", " " + ), + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md009, + ), + pluginRuleTest( + "bad_improper_indent_setext_in_list_item", + source_file_name=f"{source_path}improper_indent_setext_in_list_item.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md005_md030_md032, + source_file_contents="""- Some text - Heading 2 - md030 warns of too many spaces, md023 does not trigger --------- @@ -779,27 +269,12 @@ def test_md023_bad_improper_indent_setext_in_list_item_fix(): - Normal Heading --------- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - # "--log-level", - # "DEBUG", - # "-x-fix-no-rescan-log", - "--enable-rules", - "MD023", - "--disable-rules", - "MD005,md030,md032", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """- Some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:9:6: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:22:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +""", + fix_expected_file_contents="""- Some text - Heading 2 - md030 warns of too many spaces, md023 does not trigger --------- @@ -824,219 +299,132 @@ def test_md023_bad_improper_indent_setext_in_list_item_fix(): - Normal Heading --------- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md023_good_proper_indented_atx_after_emphasis(): - """ - Test to make sure this rule does not trigger with a document that - contains a "SetExt heading" that is encapsulated in emphasis. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "improper_indented_atx_after_emphasis.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "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_md023_proper_indent_setext_trailing_x(): - """ - Test to make sure this rule does not trigger with a document that - contains a SetExt heading that ends with spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "proper_indent_setext_trailing.md" - ) - supplied_arguments = [ - "--disable-rules", - "MD009", - "--enable-rules", - "MD023", - "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_md023_proper_indent_setext_trailing_first(): - """ - Test to make sure this rule does not trigger with a document that - contains a SetExt heading that ends with spaces on the first line. - """ +""", + ), + pluginRuleTest( + "good_proper_indented_atx_after_emphasis", + source_file_name=f"{source_path}improper_indented_atx_after_emphasis.md", + enable_rules=plugin_enable_this_rule, + ), + pluginRuleTest( + "good_proper_indent_setext_trailing_x", + source_file_name=f"{source_path}proper_indent_setext_trailing.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md009, + ), + pluginRuleTest( + "proper_indent_setext_trailing_first", + source_file_name=f"{source_path}proper_indent_setext_trailing_first.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md009, + ), + pluginRuleTest( + "proper_indent_setext_trailing_second", + source_file_name=f"{source_path}proper_indent_setext_trailing_second.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md009, + ), + pluginRuleTest( + "proper_indent_setext_trailing_third", + source_file_name=f"{source_path}proper_indent_setext_trailing_third.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md009, + ), + pluginRuleTest( + "proper_indent_setext_larger_trailing_middle", + source_file_name=f"{source_path}proper_indent_setext_larger_trailing_middle.md", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md009, + ), + pluginRuleTest( + "mix_md023_md009", + source_file_contents=""" ## Heading 2\a\a\a - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "proper_indent_setext_trailing_first.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "--disable-rules", - "MD009", - "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_md023_proper_indent_setext_trailing_second(): - """ - Test to make sure this rule does not trigger with a document that - contains a SetExt heading that ends with spaces on the second line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "proper_indent_setext_trailing_second.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "--disable-rules", - "MD009", - "scan", - source_path, - ] - - expected_return_code = 0 - expected_output = "" - expected_error = "" +Some more text +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:1:15: MD009: Trailing spaces [Expected: 0 or 2; Actual: 3] (no-trailing-spaces) +""", + fix_expected_file_contents="""## Heading 2\a\a - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) +Some more text +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "mix_md023_md019", + source_file_contents=""" # Heading 1 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +{temp_source_path}:1:3: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +""", + fix_expected_file_contents="""# Heading 1 +""", + ), + pluginRuleTest( + "mix_md023_md030", + source_file_contents=""" * # Heading 1 + + * ## Heading 2 + + * ### Heading 3 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:1:2: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:5: MD007: Unordered list indentation [Expected: 2, Actual=4] (ul-indent) +{temp_source_path}:3:5: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:8: MD007: Unordered list indentation [Expected: 4, Actual=7] (ul-indent) +{temp_source_path}:5:8: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* # Heading 1 + + * ## Heading 2 + + * ### Heading 3 +""", + ), + pluginRuleTest( + "mix_md023_md027", + source_file_contents="""> # Heading 1 +> +> ## Heading 2 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:1:4: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:3:4: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +""", + fix_expected_file_contents="""> # Heading 1 +> +> ## Heading 2 +""", + ), +] - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) -@pytest.mark.rules -def test_md023_proper_indent_setext_trailing_third(): +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md023_scan(test: pluginRuleTest) -> None: """ - Test to make sure this rule does not trigger with a document that - contains a SetExt heading that ends with spaces on the third line. + Execute a parameterized scan test for plugin md001. """ + execute_scan_test(test, "md023") - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md023", "proper_indent_setext_trailing_third.md" - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "--disable-rules", - "MD009", - "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_md023_proper_indent_setext_larger_trailing_middle(): +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md023_fix(test: pluginRuleTest) -> None: """ - Test to make sure this rule does not trigger with a document that - contains a SetExt heading that ends with spaces in the middle. + Execute a parameterized fix test for plugin md001. """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md023", - "proper_indent_setext_larger_trailing_middle.md", - ) - supplied_arguments = [ - "--enable-rules", - "MD023", - "--disable-rules", - "MD009", - "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 - ) + execute_fix_test(test) diff --git a/test/rules/test_md027.py b/test/rules/test_md027.py index 85d9e74b2..5e4f62d57 100644 --- a/test/rules/test_md027.py +++ b/test/rules/test_md027.py @@ -2,8 +2,12 @@ Module to provide tests related to the MD027 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, +) import pytest @@ -12,3249 +16,710 @@ source_path = os.path.join("test", "resources", "rules", "md027") + os.sep -@pytest.mark.rules -def test_md027_good_block_quote_empty(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with nothing after it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_empty.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_md027_good_block_quote_empty_just_blank(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with only a single space after it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_empty_just_blank.md" - ) - supplied_arguments = [ - "--disable-rules", - "md009", - "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_md027_bad_block_quote_empty_too_many_spaces(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_empty_too_many_spaces.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_empty_too_many_spaces_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_empty_too_many_spaces.md" - ) as temp_source_path: - original_file_contents = """>\a\a +__plugin_disable_md003_md013_md022 = "md003,md013,md022" +__plugin_disable_md005 = "md005" +__plugin_disable_md005_md007 = "md005,md007" +__plugin_disable_md005_md030 = "md005,md030" +__plugin_disable_md007 = "md007" +__plugin_disable_md009 = "md009" +__plugin_disable_md009_md028 = "md009,md028" +__plugin_disable_md012 = "md012" +__plugin_disable_md022 = "MD022" +__plugin_disable_md022_md023 = "md022,md023" +__plugin_disable_md023 = "md023" +__plugin_disable_md028 = "md028" +__plugin_disable_md031 = "md031" +__plugin_disable_md031_md032 = "md031,md032" +__plugin_disable_md032 = "md032" + + +scanTests = [ + pluginRuleTest( + "good_block_quote_empty", + source_file_name=f"{source_path}good_block_quote_empty.md", + ), + pluginRuleTest( + "good_block_quote_empty_just_blank", + source_file_name=f"{source_path}good_block_quote_empty_just_blank.md", + source_file_contents="""> +""", + ), + pluginRuleTest( + "bad_block_quote_empty_too_many_spaces", + source_file_name=f"{source_path}bad_block_quote_empty_too_many_spaces.md", + source_file_contents=""">\a\a """.replace( "\a", " " - ) - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_simple_text(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with simple text - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_simple_text.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_md027_good_block_quote_followed_by_heading(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with simple text, an Atx Heading, and more text - within it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_followed_by_heading.md" - ) - supplied_arguments = [ - "--disable-rules", - "md022", - "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_md027_good_block_quote_indent(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with simple text. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_indent.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_md027_bad_block_quote_indent(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with simple text, indented an extra space. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_indent.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_indent_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_indent.md" - ) as temp_source_path: - original_file_contents = """> this is text + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> +""", + ), + pluginRuleTest( + "bad_block_quote_empty_one_too_many_spaces", + source_file_contents=""">\a +""".replace( + "\a", " " + ), + disable_rules=__plugin_disable_md009, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> +""", + ), + pluginRuleTest( + "bad_block_quote_multiple_empty_one_too_many_spaces", + source_file_contents=""">\a +> abc +>\a +> def +""".replace( + "\a", " " + ), + disable_rules=__plugin_disable_md009, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:3:2: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> +> abc +> +> def +""", + ), + pluginRuleTest( + "bad_block_quote_multiple_empty_one_too_many_spaces_xx", + source_file_contents=""">\a +> abc +>\a +> def +>\a +""".replace( + "\a", " " + ), + disable_rules=__plugin_disable_md009, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:3:2: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:5:2: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> +> abc +> +> def +> +""", + ), + pluginRuleTest( + "good_block_quote_simple_text", + source_file_name=f"{source_path}good_block_quote_simple_text.md", + ), + pluginRuleTest( + "good_block_quote_followed_by_heading", + source_file_name=f"{source_path}good_block_quote_followed_by_heading.md", + disable_rules=__plugin_disable_md022, + ), + pluginRuleTest( + "good_block_quote_indent", + source_file_name=f"{source_path}good_block_quote_indent.md", + ), + pluginRuleTest( + "bad_block_quote_indent", + source_file_name=f"{source_path}bad_block_quote_indent.md", + source_file_contents="""> this is text > within a block quote -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_indent_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with simple text indented by 2 spaces, with - the entire block being indented by 1 space. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_indent_plus_one.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:2:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_indent_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_indent_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_indent_plus_one", + source_file_name=f"{source_path}bad_block_quote_indent_plus_one.md", + source_file_contents=""" > this is text > within a block quote -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:2:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_only_one_properly_indented(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text, where only one line is properly - indented. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_only_one_properly_indented.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_only_one_properly_indented_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_only_one_properly_indented.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_only_one_properly_indented", + source_file_name=f"{source_path}bad_block_quote_only_one_properly_indented.md", + source_file_contents="""> this is text > within a block quote -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_only_one_properly_indented_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text, where only one line is properly - indented, with the entire block being indented by 1. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_only_one_properly_indented_plus_one.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_only_one_properly_indented_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_only_one_properly_indented_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_only_one_properly_indented_plus_one", + source_file_name=f"{source_path}bad_block_quote_only_one_properly_indented_plus_one.md", + source_file_contents=""" > this is text > within a block quote -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_indent_with_blank(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with text and a blank line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_indent_with_blank.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_md027_good_block_quote_indent_with_blank_space(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with text and a blank line that has a single space. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_indent_with_blank_space.md", - ) - supplied_arguments = [ - "--disable-rules", - "md009", - "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_md027_bad_block_quote_indent_with_blank_two_spaces(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a blank line that has two spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_indent_with_blank_two_spaces.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_indent_with_blank_two_spaces_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_indent_with_blank_two_spaces.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_indent_with_blank", + source_file_name=f"{source_path}good_block_quote_indent_with_blank.md", + ), + pluginRuleTest( + "good_block_quote_indent_with_blank_space", + source_file_name=f"{source_path}good_block_quote_indent_with_blank_space.md", + ), + pluginRuleTest( + "bad_block_quote_indent_with_blank_two_spaces", + source_file_name=f"{source_path}bad_block_quote_indent_with_blank_two_spaces.md", + source_file_contents="""> this is text >\a\a > within a block quote """.replace( "\a", " " - ) - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_indent_with_blank_two_spaces_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a blank line that has two spaces, - the entire block being indented by 1. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_indent_with_blank_two_spaces_plus_one.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_indent_with_blank_two_spaces_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_indent_with_blank_two_spaces_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_indent_with_blank_two_spaces_plus_one", + source_file_name=f"{source_path}bad_block_quote_indent_with_blank_two_spaces_plus_one.md", + source_file_contents=""" > this is text >\a\a > within a block quote """.replace( "\a", " " - ) - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_indent_with_blank_two_spaces_misaligned(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a blank line that has two spaces, - even though the line has extra indent before the block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_indent_with_blank_two_spaces_misaligned.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_indent_with_blank_two_spaces_misaligned_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_indent_with_blank_two_spaces_misaligned.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_indent_with_blank_two_spaces_misaligned", + source_file_name=f"{source_path}bad_block_quote_indent_with_blank_two_spaces_misaligned.md", + source_file_contents=""" > this is text >\a\a > within a block quote """.replace( "\a", " " - ) - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_indent_with_blank_space_no_start(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with text and a blank line that has no bq start. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_indent_with_blank_space_no_start.md", - ) - supplied_arguments = [ - "--disable-rules", - "md009,md028", - "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_md027_bad_two_block_quotes_space_top(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text, where the top has extra space. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_two_block_quotes_space_top.md" - ) - supplied_arguments = [ - "--disable-rules", - "md028", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_two_block_quotes_space_top_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_two_block_quotes_space_top.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_indent_with_blank_space_no_start", + source_file_name=f"{source_path}good_block_quote_indent_with_blank_space_no_start.md", + disable_rules=__plugin_disable_md009_md028, + ), + pluginRuleTest( + "bad_two_block_quotes_space_top", + source_file_name=f"{source_path}bad_two_block_quotes_space_top.md", + disable_rules=__plugin_disable_md028, + source_file_contents="""> this is text > within a block quote -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md028", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_two_block_quotes_space_bottom(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text, where the bottom has extra space. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_two_block_quotes_space_bottom.md" - ) - supplied_arguments = [ - "--disable-rules", - "md028", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) +""", + ), + pluginRuleTest( + "bad_two_block_quotes_space_bottom", + source_file_name=f"{source_path}bad_two_block_quotes_space_bottom.md", + disable_rules=__plugin_disable_md028, + source_file_contents="""> this is text - -@pytest.mark.rules -def test_md027_bad_two_block_quotes_space_bottom_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_two_block_quotes_space_bottom.md" - ) as temp_source_path: - original_file_contents = """> this is text - -> within a block quote -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md028", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +> within a block quote +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_misalligned_double_quote(): - """ - Test to make sure this rule does trigger with a document that - contains a double block quote with text, where the text is aligned - even though the block quotes are not. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_misalligned_double_quote.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_misalligned_double_quote_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_misalligned_double_quote.md" - ) as temp_source_path: - original_file_contents = """> > this is text +""", + ), + pluginRuleTest( + "bad_misalligned_double_quote", + source_file_name=f"{source_path}bad_misalligned_double_quote.md", + source_file_contents="""> > this is text >> within a block quote -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> > this is text >> within a block quote -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_aligned_double_quote(): - """ - Test to make sure this rule does not trigger with a document that - contains a double block quote with text that is aligned to the block - quote, not the text. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_alligned_double_quote.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_md027_bad_misindented_quote_within_list(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a list and text, with a misindented block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_misindented_quote_within_list.md" - ) - supplied_arguments = [ - "--disable-rules", - "md032", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_misindented_quote_within_list_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_misindented_quote_within_list.md" - ) as temp_source_path: - original_file_contents = """- > this is a quote +""", + ), + pluginRuleTest( + "good_aligned_double_quote", + source_file_name=f"{source_path}good_alligned_double_quote.md", + ), + pluginRuleTest( + "bad_misindented_quote_within_list", + source_file_name=f"{source_path}bad_misindented_quote_within_list.md", + disable_rules=__plugin_disable_md032, + source_file_contents="""- > this is a quote > this is the second line -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md032", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """- > this is a quote +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""- > this is a quote > this is the second line -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_misalligned_quote_within_list(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a list and text, with a misaligned block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_misalligned_quote_within_list.md" - ) - supplied_arguments = [ - "--disable-rules", - "md032", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:5: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_misalligned_quote_within_list_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_misalligned_quote_within_list.md" - ) as temp_source_path: - original_file_contents = """- > this is a quote +""", + ), + pluginRuleTest( + "bad_misalligned_quote_within_list", + source_file_name=f"{source_path}bad_misalligned_quote_within_list.md", + source_file_contents="""- > this is a quote > this is the second line -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md032", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """- > this is a quote +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:5: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""- > this is a quote > this is the second line -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_aligned_quote_within_list(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a list and text, all properly aligned. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_alligned_quote_within_list.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_md027_good_fenced_block_in_list_in_block_quote(): - """ - A fenced block Within a block quote, surrounded on both sides by lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_fenced_block_in_list_in_block_quote.md", - ) - supplied_arguments = [ - "--disable-rules", - "md031,md032", - "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_md027_good_list_within_block_quote_surrounded(): - """ - Block quote containing a paragraph and a single item list, with paragraphs - and newlines around the block quote - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_list_within_block_quote_surrounded.md", - ) - supplied_arguments = [ - "--disable-rules", - "md032", - "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_md027_good_block_quote_list_block_quote(): - """ - Single line blocks quotes on either side of a list. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_list_block_quote.md" - ) - supplied_arguments = [ - "--disable-rules", - "md032", - "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_md027_good_multiple_blanks_in_block_quote(): - """ - Block quote with two paragraphs and multiple blanks between them. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_multiple_blanks_in_block_quote.md" - ) - supplied_arguments = [ - "--disable-rules", - "md012", - "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_md027_good_indentation_in_block_quote(): - """ - List with 2 items inside of a block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_indentation_in_block_quote.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_md027_good_items_with_multiple_lines_in_block_quote(): - """ - List with 2 items inside of a block quote. First item has multiple lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_items_with_multiple_lines_in_block_quote.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_md027_good_thematic_break_in_block_quote(): - """ - Block quote with two single line paragraphs and a thematic break between them. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_thematic_break_in_block_quote.md" - ) - supplied_arguments = [ - "--disable-rules", - "md022", - "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_md027_good_indented_code_block_in_block_quote(): - """ - Block quote with two single line paragraphs and an indented code block - break between them. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_indented_code_block_in_block_quote.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_md027_bad_block_quote_misindented_unordered_list_first(): - """ - Block quote with a misaligned multiline unordered list and a properly - aligned unordered list to follow. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_misindented_unordered_list_first.md", - ) - supplied_arguments = [ - "--disable-rules", - "md005,md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_misindented_unordered_list_first_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_misindented_unordered_list_first.md" - ) as temp_source_path: - original_file_contents = """> + list +""", + ), + pluginRuleTest( + "good_aligned_quote_within_list", + source_file_name=f"{source_path}good_alligned_quote_within_list.md", + ), + pluginRuleTest( + "good_fenced_block_in_list_in_block_quote", + source_file_name=f"{source_path}good_fenced_block_in_list_in_block_quote.md", + disable_rules=__plugin_disable_md031_md032, + ), + pluginRuleTest( + "good_list_within_block_quote_surrounded", + source_file_name=f"{source_path}good_list_within_block_quote_surrounded.md", + disable_rules=__plugin_disable_md032, + ), + pluginRuleTest( + "good_block_quote_list_block_quote", + source_file_name=f"{source_path}good_block_quote_list_block_quote.md", + disable_rules=__plugin_disable_md032, + ), + pluginRuleTest( + "good_multiple_blanks_in_block_quote", + source_file_name=f"{source_path}bad_multiple_blanks_in_block_quote.md", + disable_rules=__plugin_disable_md012, + ), + pluginRuleTest( + "good_indentation_in_block_quote", + source_file_name=f"{source_path}good_indentation_in_block_quote.md", + ), + pluginRuleTest( + "good_items_with_multiple_lines_in_block_quote", + source_file_name=f"{source_path}good_items_with_multiple_lines_in_block_quote.md", + ), + pluginRuleTest( + "good_thematic_break_in_block_quote", + source_file_name=f"{source_path}good_thematic_break_in_block_quote.md", + disable_rules=__plugin_disable_md022, + ), + pluginRuleTest( + "good_indented_code_block_in_block_quote", + source_file_name=f"{source_path}good_indented_code_block_in_block_quote.md", + ), + pluginRuleTest( + "bad_block_quote_misindented_unordered_list_first", + source_file_name=f"{source_path}bad_block_quote_misindented_unordered_list_first.md", + disable_rules=__plugin_disable_md005_md007, + source_file_contents="""> + list > this > + that -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md005,md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> + list +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> + list > this > + that -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_misindented_ordered_list_first(): - """ - Block quote with a misaligned multiline ordered list and a properly - aligned ordered list to follow. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_misindented_ordered_list_first.md", - ) - supplied_arguments = [ - "--disable-rules", - "md005,md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_misindented_ordered_list_first_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_misindented_ordered_list_first.md" - ) as temp_source_path: - original_file_contents = """> 1. list +""", + ), + pluginRuleTest( + "bad_block_quote_misindented_ordered_list_first", + source_file_name=f"{source_path}bad_block_quote_misindented_ordered_list_first.md", + disable_rules=__plugin_disable_md005, + source_file_contents="""> 1. list > this > 1. that -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md005,md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> 1. list +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> 1. list > this > 1. that -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_misindented_unordered_list_last(): - """ - Block quote with an aligned multiline unordered list and a misaligned - unordered list to follow. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_misindented_unordered_list_last.md", - ) - supplied_arguments = [ - "--disable-rules", - "md005,md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_misindented_unordered_list_last_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_misindented_unordered_list_last.md" - ) as temp_source_path: - original_file_contents = """> + list +""", + ), + pluginRuleTest( + "bad_block_quote_misindented_unordered_list_last", + source_file_name=f"{source_path}bad_block_quote_misindented_unordered_list_last.md", + disable_rules=__plugin_disable_md005_md007, + source_file_contents="""> + list > this > + that -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md005,md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> + list +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> + list > this > + that -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_misindented_ordered_list_last(): - """ - Block quote with an aligned multiline ordered list and a misaligned - ordered list to follow. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_misindented_ordered_list_last.md", - ) - supplied_arguments = [ - "--disable-rules", - "md005,md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_misindented_ordered_list_last_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_misindented_ordered_list_last.md" - ) as temp_source_path: - original_file_contents = """> 1. list +""", + ), + pluginRuleTest( + "bad_block_quote_misindented_ordered_list_last", + source_file_name=f"{source_path}bad_block_quote_misindented_ordered_list_last.md", + disable_rules=__plugin_disable_md005, + source_file_contents="""> 1. list > this > 1. that -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--stack-trace", - "--disable-rules", - "md005,md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> 1. list +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> 1. list > this > 1. that -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_unordered_list(): - """ - Block quote with an aligned multiline unordered list and an aligned - unordered list to follow. - """ +""", + ), + pluginRuleTest( + "good_block_quote_unordered_list", + source_file_name=f"{source_path}good_block_quote_unordered_list.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list", + source_file_name=f"{source_path}good_block_quote_ordered_list.md", + ), + pluginRuleTest( + "good_block_quote_unordered_list_unordered_list", + source_file_name=f"{source_path}good_block_quote_unordered_list_unordered_list.md", + ), + pluginRuleTest( + "good_block_quote_unordered_list_ordered_list", + source_file_name=f"{source_path}good_block_quote_unordered_list_ordered_list.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_ordered_list", + source_file_name=f"{source_path}good_block_quote_ordered_list_ordered_list.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_unordered_list", + source_file_name=f"{source_path}good_block_quote_ordered_list_unordered_list.md", + ), + pluginRuleTest( + "good_block_quote_unordered_list_block_quote_text", + source_file_name=f"{source_path}good_block_quote_ordered_list_unordered_list.md", + ), + pluginRuleTest( + "bad_block_quote_unordered_list_block_quote_text_first", + source_file_name=f"{source_path}bad_block_quote_unordered_list_block_quote_text_first.md", + source_file_contents="""> + list +> this +> > good +> > item +> + that +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> + list +> this +> > good +> > item +> + that +""", + ), + pluginRuleTest( + "bad_block_quote_unordered_list_block_quote_text_last", + source_file_name=f"{source_path}bad_block_quote_unordered_list_block_quote_text_last.md", + source_file_contents="""> + list +> this +> > good +> > item +> + that +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:7: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> + list +> this +> > good +> > item +> + that +""", + ), + pluginRuleTest( + "good_block_quote_ordered_list_thematic_break", + source_file_name=f"{source_path}good_block_quote_ordered_list_thematic_break.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_thematic_break_misaligned", + source_file_name=f"{source_path}good_block_quote_ordered_list_thematic_break_misaligned.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_atx_heading", + source_file_name=f"{source_path}good_block_quote_ordered_list_atx_heading.md", + disable_rules=__plugin_disable_md022, + ), + pluginRuleTest( + "good_block_quote_ordered_list_setext_heading", + source_file_name=f"{source_path}good_block_quote_ordered_list_setext_heading.md", + disable_rules=__plugin_disable_md022, + ), + pluginRuleTest( + "good_block_quote_ordered_list_setext_heading_first", + source_file_name=f"{source_path}bad_block_quote_ordered_list_setext_heading_first.md", + disable_rules=__plugin_disable_md022_md023, + ), + pluginRuleTest( + "good_block_quote_ordered_list_setext_heading_last", + source_file_name=f"{source_path}bad_block_quote_ordered_list_setext_heading_last.md", + disable_rules=__plugin_disable_md022_md023, + ), + pluginRuleTest( + "good_block_quote_ordered_list_indented_code_block", + source_file_name=f"{source_path}good_block_quote_ordered_list_indented_code_block.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_indented_code_block_first", + source_file_name=f"{source_path}bad_block_quote_ordered_list_indented_code_block_first.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_indented_code_block_last", + source_file_name=f"{source_path}bad_block_quote_ordered_list_indented_code_block_last.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_fenced_code_block", + source_file_name=f"{source_path}good_block_quote_ordered_list_fenced_code_block.md", + disable_rules=__plugin_disable_md031, + ), + pluginRuleTest( + "good_block_quote_ordered_list_fenced_code_block_indent_first", + source_file_name=f"{source_path}good_block_quote_ordered_list_fenced_code_block_indent_first.md", + disable_rules=__plugin_disable_md031, + ), + pluginRuleTest( + "good_block_quote_ordered_list_fenced_code_block_indent_second", + source_file_name=f"{source_path}good_block_quote_ordered_list_fenced_code_block_indent_second.md", + disable_rules=__plugin_disable_md031, + ), + pluginRuleTest( + "good_block_quote_ordered_list_fenced_code_block_indent_third", + source_file_name=f"{source_path}good_block_quote_ordered_list_fenced_code_block_indent_third.md", + disable_rules=__plugin_disable_md031, + ), + pluginRuleTest( + "good_block_quote_ordered_list_html_block", + source_file_name=f"{source_path}good_block_quote_ordered_list_html_block.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_html_block_with_indent", + source_file_name=f"{source_path}good_block_quote_ordered_list_html_block_with_indent.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_html_block_with_multiline", + source_file_name=f"{source_path}good_block_quote_ordered_list_html_block_with_multiline.md", + ), + pluginRuleTest( + "good_block_quote_ordered_list_lrd", + source_file_name=f"{source_path}good_block_quote_ordered_list_lrd.md", + use_debug=True, + ), + pluginRuleTest( + "good_list_in_block_quote_after_other_list", + source_file_name=f"{source_path}bad_list_in_block_quote_after_other_list.md", + disable_rules=__plugin_disable_md007, + ), + pluginRuleTest( + "bad_list_indentation_in_block_quote_level_0", + source_file_name=f"{source_path}test_md007_bad_list_indentation_in_block_quote_level_0.md", + disable_rules=__plugin_disable_md007, + source_file_contents="""This is a test - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_unordered_list.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_md027_good_block_quote_ordered_list(): - """ - Block quote with an aligned multiline ordered list and an aligned - ordered list to follow. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_ordered_list.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_md027_good_block_quote_unordered_list_unordered_list(): - """ - Block quote with an aligned multiline ordered list and an aligned - ordered list to follow, with another level of an unordered list in - the middle. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_unordered_list_unordered_list.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_md027_good_block_quote_unordered_list_ordered_list(): - """ - Block quote with an aligned multiline ordered list and an aligned - ordered list to follow, with another level of an ordered list in - the middle. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_unordered_list_ordered_list.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_md027_good_block_quote_ordered_list_ordered_list(): - """ - Block quote with an aligned multiline ordered list and an aligned - ordered list to follow, with another level of an ordered list in - the middle. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_ordered_list.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_md027_good_block_quote_ordered_list_unordered_list(): - """ - Block quote with an aligned multiline ordered list and an aligned - ordered list to follow, with another level of an unordered list in - the middle. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_unordered_list.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "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_md027_good_block_quote_unordered_list_block_quote_text(): - """ - Block quote with an aligned multiline list and an aligned block - quote within it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_unordered_list.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "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_md027_bad_block_quote_unordered_list_block_quote_text_first(): - """ - Block quote with an aligned multiline list and an aligned block - quote within it, but text with an extra space on the first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_unordered_list_block_quote_text_first.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_unordered_list_block_quote_text_first_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_unordered_list_block_quote_text_first.md" - ) as temp_source_path: - original_file_contents = """> + list -> this -> > good -> > item -> + that -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> + list -> this -> > good -> > item -> + that -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_unordered_list_block_quote_text_last(): - """ - Block quote with an aligned multiline list and an aligned block - quote within it, but text with an extra space on the last line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_unordered_list_block_quote_text_last.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:7: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_unordered_list_block_quote_text_last_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_unordered_list_block_quote_text_last.md" - ) as temp_source_path: - original_file_contents = """> + list -> this -> > good -> > item -> + that -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> + list -> this -> > good -> > item -> + that -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_ordered_list_thematic_break(): - """ - Block quote with an aligned multiline list followed by a thematic break. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_thematic_break.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_md027_good_block_quote_ordered_list_thematic_break_misaligned(): - """ - Block quote with an aligned multiline list followed by a thematic break - which is misaligned. The misalignment should not matter as it occurs - within the list's scope, and not the block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_thematic_break_misaligned.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_md027_good_block_quote_ordered_list_atx_heading(): - """ - Block quote with an aligned multiline list followed by an Atx Heading. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_atx_heading.md", - ) - supplied_arguments = [ - "--disable-rules", - "md022,md023,md032", - "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_md027_good_block_quote_ordered_list_setext_heading(): - """ - Block quote with an aligned multiline list followed by an Atx Heading. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_setext_heading.md", - ) - supplied_arguments = [ - "--disable-rules", - "md022,md023", - "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_md027_bad_block_quote_ordered_list_setext_heading_first(): - """ - Block quote with an aligned multiline list followed by a SetExt Heading - with a misaligned first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_ordered_list_setext_heading_first.md", - ) - supplied_arguments = [ - "--disable-rules", - "md022,md023", - "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_md027_bad_block_quote_ordered_list_setext_heading_last(): - """ - Block quote with an aligned multiline list followed by a SetExt Heading - with a misaligned last line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_ordered_list_setext_heading_last.md", - ) - supplied_arguments = [ - "--disable-rules", - "md022,md023", - "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_md027_good_block_quote_ordered_list_indented_code_block(): - """ - Block quote with an aligned multiline list followed by an indented code block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_indented_code_block.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_md027_good_block_quote_ordered_list_indented_code_block_first(): - """ - Block quote with an aligned multiline list followed by an indented code block - with the first line added an extra space. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_ordered_list_indented_code_block_first.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_md027_good_block_quote_ordered_list_indented_code_block_last(): - """ - Block quote with an aligned multiline list followed by an indented code block - with the last line added an extra space. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_ordered_list_indented_code_block_last.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_md027_good_block_quote_ordered_list_fenced_code_block(): - """ - Block quote with an aligned multiline list followed by a fecned code block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_fenced_code_block.md", - ) - supplied_arguments = [ - "--disable-rules", - "md031,md032", - "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_md027_good_block_quote_ordered_list_fenced_code_block_indent_first(): - """ - Block quote with an aligned multiline list followed by a fecned code block - and an indent on the first line of the block. - - Note that the indent is closest to the list, so this rule will not fire. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_fenced_code_block_indent_first.md", - ) - supplied_arguments = [ - "--disable-rules", - "md031,md032", - "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_md027_good_block_quote_ordered_list_fenced_code_block_indent_second(): - """ - Block quote with an aligned multiline list followed by a fecned code block - and an indent on the second line of the block. - - Note that the indent is closest to the list, so this rule will not fire. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_fenced_code_block_indent_second.md", - ) - supplied_arguments = [ - "--disable-rules", - "md031,md032", - "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_md027_good_block_quote_ordered_list_fenced_code_block_indent_third(): - """ - Block quote with an aligned multiline list followed by a fecned code block - and an indent on the third line of the block. - - Note that the indent is closest to the list, so this rule will not fire. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_fenced_code_block_indent_third.md", - ) - supplied_arguments = [ - "--disable-rules", - "md031,md032", - "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_md027_good_block_quote_ordered_list_html_block(): - """ - Block quote with an aligned multiline list followed by a HTML block. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_html_block.md", - ) - supplied_arguments = [ - "--disable-rules", - "md032", - "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_md027_good_block_quote_ordered_list_html_block_with_indent(): - """ - Block quote with an aligned multiline list followed by a HTML block that is - indented past the list. - - Note that because HTML blocks are blocks, any indent belongs to the HTML Block - itself, and is not considered to be extra. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_html_block_with_indent.md", - ) - supplied_arguments = [ - "--disable-rules", - "md032", - "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_md027_good_block_quote_ordered_list_html_block_with_multiline(): - """ - Block quote with an aligned multiline list followed by a HTML block that has - multiple lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_ordered_list_html_block_with_multiline.md", - ) - supplied_arguments = [ - "--disable-rules", - "md032", - "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_md027_good_block_quote_ordered_list_lrd(): - """ - Block quote with an aligned multiline list followed by an LRD. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_ordered_list_lrd.md" - ) - supplied_arguments = [ - "--disable-rules", - "md032", - "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_md027_good_list_in_block_quote_after_other_list(): - """ - TBD - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_list_in_block_quote_after_other_list.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "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_md027_bad_list_indentation_in_block_quote_level_0(): - """ - Three levels of nested unordered list items within a block quote, each item - with simple text. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "test_md007_bad_list_indentation_in_block_quote_level_0.md", - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_list_indentation_in_block_quote_level_0_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "test_md007_bad_list_indentation_in_block_quote_level_0.md" - ) as temp_source_path: - original_file_contents = """This is a test - -> * this is level 1 -> * this is level 2 -> * this is level 3 -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--stack-trace", - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """This is a test +> * this is level 1 +> * this is level 2 +> * this is level 3 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""This is a test > * this is level 1 > * this is level 2 > * this is level 3 -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_unordered_list_text_first(): - """ - Block quote with an aligned multiline list including multiline text with - a misaligned first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_unordered_list_text_first.md", - ) - supplied_arguments = [ - "--disable-rules", - "md005,md030", - "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_md027_good_block_quote_unordered_list_text_last(): - """ - Block quote with an aligned multiline list including multiline text with - a misaligned second line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_unordered_list_text_last.md", - ) - supplied_arguments = [ - "--disable-rules", - "md005,md030", - "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_md027_good_block_quote_with_trailing_empty_line(): - """ - TBD - reported as https://github.com/jackdewinter/pymarkdown/issues/189 - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_with_trailing_empty_line.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_md027_issue_189(): - """ - TBD - reported as https://github.com/jackdewinter/pymarkdown/issues/189 - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join("test", "resources", "rules", "md027", "issue-189.md") - supplied_arguments = [ - "--disable-rules", - "md003,md013,md022", - "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_md027_issue_189_mini(): - """ - TBD - reported as https://github.com/jackdewinter/pymarkdown/issues/189 - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "issue-189-mini.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 - ) +""", + ), + pluginRuleTest( + "good_block_quote_unordered_list_text_first", + source_file_name=f"{source_path}bad_block_quote_unordered_list_text_first.md", + disable_rules=__plugin_disable_md005_md030, + ), + pluginRuleTest( + "good_block_quote_unordered_list_text_last", + source_file_name=f"{source_path}bad_block_quote_unordered_list_text_last.md", + ), + pluginRuleTest( + "good_block_quote_with_trailing_empty_line", + source_file_name=f"{source_path}good_block_quote_with_trailing_empty_line.md", + ), + pluginRuleTest( + "issue_189", + source_file_name=f"{source_path}issue-189.md", + disable_rules=__plugin_disable_md003_md013_md022, + ), + pluginRuleTest( + "issue_189_mini", + source_file_name=f"{source_path}issue-189-mini.md", + ), + pluginRuleTest( + "mix_md027_md007", + source_file_contents="""> + first +> + second +> + third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:1:4: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:2:7: MD007: Unordered list indentation [Expected: 2, Actual=4] (ul-indent) +{temp_source_path}:3:9: MD007: Unordered list indentation [Expected: 4, Actual=6] (ul-indent) +""", + fix_expected_file_contents="""> + first +> + second +> + third +""", + ), + pluginRuleTest( + "mix_md027_md009", + disable_rules=__plugin_disable_md023, + source_file_contents="""> # Header 1\a +> +> ## Header 2\a\a\a +""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:1:14: MD009: Trailing spaces [Expected: 0 or 2; Actual: 1] (no-trailing-spaces) +{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:3:15: MD009: Trailing spaces [Expected: 0 or 2; Actual: 3] (no-trailing-spaces) +""", + fix_expected_file_contents="""> # Header 1 +> +> ## Header 2\a\a +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "mix_md027_md023", + source_file_contents="""> # Heading 1 +> +> ## Heading 2 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:1:4: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:3:4: MD023: Headings must start at the beginning of the line. (heading-start-left, header-start-left) +""", + fix_expected_file_contents="""> # Heading 1 +> +> ## Heading 2 +""", + ), + pluginRuleTest( + "mix_md027_md030", + source_file_contents="""> * Heading 1 +> * Heading 2 +""", + disable_rules=__plugin_disable_md007, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:1:4: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:2:4: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""> * Heading 1 +> * Heading 2 +""", + ), + pluginRuleTest( + "mix_md027_md005", + source_file_contents="""> * Heading 1 +> * Heading 2 +""", + disable_rules=__plugin_disable_md007, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:2:5: MD005: Inconsistent indentation for list items at the same level [Expected: 3; Actual: 4] (list-indent) +""", + fix_expected_file_contents="""> * Heading 1 +> * Heading 2 +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md027_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md027") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md027_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) diff --git a/test/rules/test_md027_inline.py b/test/rules/test_md027_inline.py index affb61dd1..c0c84790b 100644 --- a/test/rules/test_md027_inline.py +++ b/test/rules/test_md027_inline.py @@ -2,1285 +2,316 @@ Module to provide tests related to the MD027 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, +) import pytest source_path = os.path.join("test", "resources", "rules", "md027") + os.sep - -@pytest.mark.rules -def test_md027_good_block_quote_code_span(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a single line code span with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_code_span.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_md027_bad_block_quote_code_span_multiple(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multiple line code span with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_code_span_multiple.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_code_span_multiple_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_code_span_multiple.md" - ) as temp_source_path: - original_file_contents = """> this is text +scanTests = [ + pluginRuleTest( + "good_block_quote_code_span", + source_file_name=f"{source_path}good_block_quote_code_span.md", + ), + pluginRuleTest( + "bad_block_quote_code_span_multiple", + source_file_name=f"{source_path}bad_block_quote_code_span_multiple.md", + source_file_contents="""> this is text > `code > span` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > `code > span` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_code_span_multiple_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multiple line code span with extra spaces, - and the block quote indented. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_code_span_multiple_plus_one.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_code_span_multiple_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_code_span_multiple_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_code_span_multiple_plus_one", + source_file_name=f"{source_path}bad_block_quote_code_span_multiple_plus_one.md", + source_file_contents=""" > this is text > `code > span` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > `code > span` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_code_span_multiple_misaligned(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multiple line code span with extra spaces, - where the block quotes are misaligned. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_code_span_multiple_misaligned.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_code_span_multiple_misaligned_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_code_span_multiple_misaligned.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_code_span_multiple_misaligned", + source_file_name=f"{source_path}bad_block_quote_code_span_multiple_misaligned.md", + source_file_contents=""" > this is text > `code > span` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > `code > span` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_emphasis(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a emphasis with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_emphasis.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_md027_good_block_quote_emphasis_multiple(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multi line emphasis with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_emphasis_multiple.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_good_block_quote_link(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with an inline link with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_link.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_md027_bad_block_quote_link(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an inline link with extra spaces on each line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_link.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:5:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:6:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_link_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_block_quote_link.md") as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_emphasis", + source_file_name=f"{source_path}good_block_quote_emphasis.md", + ), + pluginRuleTest( + "bad_block_quote_emphasis_multiple", + source_file_name=f"{source_path}good_block_quote_emphasis_multiple.md", + source_file_contents="""> this is *text +> that this is +> emphasis* +> a real test +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is *text +> that this is +> emphasis* +> a real test +""", + ), + pluginRuleTest( + "good_block_quote_link", + source_file_name=f"{source_path}good_block_quote_link.md", + ), + pluginRuleTest( + "bad_block_quote_link", + source_file_name=f"{source_path}bad_block_quote_link.md", + source_file_contents="""> this is text > [not so > simple]( > /link > "this is > a title") > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:5:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:6:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > [not so > simple]( > /link > "this is > a title") > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_link_multiple(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an inline link with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_link_multiple.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:5:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:6:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_good_block_quote_raw_html(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with an inline rawhtml with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_raw_html.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_md027_bad_block_quote_raw_html_multiple(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multiline inline rawhtml with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_raw_html_multiple.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_raw_html_multiple_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_raw_html_multiple.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_link_multiple", + source_file_name=f"{source_path}good_block_quote_link_multiple.md", + source_file_contents="""> this is text +> [a not +> so simple](/link +> "a +> title") +> ) +> a real test +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:5:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:6:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text +> [a not +> so simple](/link +> "a +> title") +> ) +> a real test +""", + ), + pluginRuleTest( + "good_block_quote_raw_html", + source_file_name=f"{source_path}good_block_quote_raw_html.md", + ), + pluginRuleTest( + "bad_block_quote_raw_html_multiple", + source_file_name=f"{source_path}bad_block_quote_raw_html_multiple.md", + source_file_contents="""> this is text > a huh? > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--stack-trace", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > a huh? > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_autolink(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with an inline autolink with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_autolink.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_md027_bad_block_quote_autolink(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an inline autolink with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_autolink.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_autolink_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_autolink.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_autolink", + source_file_name=f"{source_path}good_block_quote_autolink.md", + ), + pluginRuleTest( + "bad_block_quote_autolink", + source_file_name=f"{source_path}bad_block_quote_autolink.md", + source_file_contents="""> this is text > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_autolink_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an inline autolink with extra spaces, - with the block quote indented. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_autolink_plus_one.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_autolink_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_autolink_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_autolink_plus_one", + source_file_name=f"{source_path}bad_block_quote_autolink_plus_one.md", + source_file_contents=""" > this is text > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_code_span(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an inline codespan, with an extra - space before the code span. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_code_span.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_code_span_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_code_span.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_code_span", + source_file_name=f"{source_path}bad_block_quote_code_span.md", + source_file_contents="""> this is text > `code span` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > `code span` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_code_span_multiple_before(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an inline codespan over multiple - lines, with an extra space before the code span. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_code_span_multiple_before.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_code_span_multiple_before_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_code_span_multiple_before.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_code_span_multiple_before", + source_file_name=f"{source_path}bad_block_quote_code_span_multiple_before.md", + source_file_contents="""> this is text > `code > span` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > `code > span` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_emphasis_start(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote containing a line that starts with an emphasis - character. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_emphasis_start.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_md027_bad_block_quote_emphasis_start(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote containing a line that starts with an emphasis - character and a space character before it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_emphasis_start.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_emphasis_start_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_emphasis_start.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_emphasis_start", + source_file_name=f"{source_path}good_block_quote_emphasis_start.md", + ), + pluginRuleTest( + "bad_block_quote_emphasis_start", + source_file_name=f"{source_path}bad_block_quote_emphasis_start.md", + source_file_contents="""> this is text > *this* is emphasis > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > *this* is emphasis > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_image(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote containing a line that starts with an inline - image - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_image.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_md027_good_block_quote_image_multiple(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote containing a line that starts with an inline image - that spans lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_image_multiple.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:5:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:6:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_image(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote containing a line that starts with an inline image - and a space character before it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_image.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:5:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:6:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_image_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_image.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_image", + source_file_name=f"{source_path}good_block_quote_image.md", + ), + pluginRuleTest( + "good_block_quote_image_multiple", + source_file_name=f"{source_path}good_block_quote_image_multiple.md", + source_file_contents="""> this is text +> ![a not +> so simple](/link +> "a +> title") +> ) +> a real test +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:5:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:6:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text +> ![a not +> so simple](/link +> "a +> title") +> ) +> a real test +""", + ), + pluginRuleTest( + "bad_block_quote_image", + source_file_name=f"{source_path}bad_block_quote_image.md", + source_file_contents="""> this is text > ![not so > simple]( > /link > "this is > a title") > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:5:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:6:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > ![not so > simple]( > /link > "this is > a title") > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_image_multiple_extra(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote containing a line that starts with an inline image - that is over multiple lines, and a space character before it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_image_multiple_extra.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:6:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:7:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_image_multiple_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_image_multiple_extra.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_image_multiple_extra", + source_file_name=f"{source_path}bad_block_quote_image_multiple_extra.md", + source_file_contents="""> this is text > ![a not > so > simple](/link @@ -1288,20 +319,15 @@ def test_md027_bad_block_quote_image_multiple_extra_fix(): > title" > ) > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:6:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:7:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > ![a not > so > simple](/link @@ -1309,380 +335,100 @@ def test_md027_bad_block_quote_image_multiple_extra_fix(): > title" > ) > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_raw_html2(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote containing a line that starts with a HTML block - and a space character before it. - - Note that the HTML block is unique in that it gobble up the entire line - and thus cannot have an leading spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_raw_html.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_md027_good_block_quote_full_link(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote containing a line that starts with a full link. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_full_link.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_md027_bad_block_quote_full_link(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote containing a line that starts with a full link - and a single space character before it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_full_link.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_full_link_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_full_link.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_raw_html2", + source_file_name=f"{source_path}bad_block_quote_raw_html.md", + ), + pluginRuleTest( + "good_block_quote_full_link", + source_file_name=f"{source_path}good_block_quote_full_link.md", + ), + pluginRuleTest( + "bad_block_quote_full_link", + source_file_name=f"{source_path}bad_block_quote_full_link.md", + source_file_contents="""> this is text > [simple][simple] > a real test [simple]: /link -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > [simple][simple] > a real test [simple]: /link -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_collapsed_link(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote containing a line that starts with a collapsed link. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_collapsed_link.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_md027_bad_block_quote_collapsed_link(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote containing a line that starts with a collapsed link - and a single space character before it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_collapsed_link.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_collapsed_link_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_collapsed_link.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_collapsed_link", + source_file_name=f"{source_path}good_block_quote_collapsed_link.md", + ), + pluginRuleTest( + "bad_block_quote_collapsed_link", + source_file_name=f"{source_path}bad_block_quote_collapsed_link.md", + source_file_contents="""> this is text > [simple][] > a real test [simple]: /link -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > [simple][] > a real test [simple]: /link -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_shortcut_link(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote containing a line that starts with a shortcut link. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_shortcut_link.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] +""", + ), + pluginRuleTest( + "good_block_quote_shortcut_link", + source_file_name=f"{source_path}good_block_quote_shortcut_link.md", + ), + pluginRuleTest( + "bad_block_quote_shortcut_link", + source_file_name=f"{source_path}bad_block_quote_shortcut_link.md", + source_file_contents="""> this is text +> [simple] +> a real test - expected_return_code = 0 - expected_output = "" - expected_error = "" +[simple]: /link +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text +> [simple] +> a real test - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) +[simple]: /link +""", + ), +] - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) -@pytest.mark.rules -def test_md027_bad_block_quote_shortcut_link(): +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md027_scan(test: pluginRuleTest) -> None: """ - Test to make sure this rule does trigger with a document that - contains a block quote containing a line that starts with a shortcut link - and a single space character before it. + Execute a parameterized scan test for plugin md001. """ + execute_scan_test(test, "md027") - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_shortcut_link.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_shortcut_link_fix(): +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md027_fix(test: pluginRuleTest) -> None: """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. + Execute a parameterized fix test for plugin md001. """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_shortcut_link.md" - ) as temp_source_path: - original_file_contents = """> this is text -> [simple] -> a real test - -[simple]: /link -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text -> [simple] -> a real test - -[simple]: /link -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) + execute_fix_test(test) diff --git a/test/rules/test_md027_leaf.py b/test/rules/test_md027_leaf.py index 340ced48c..130ec51f9 100644 --- a/test/rules/test_md027_leaf.py +++ b/test/rules/test_md027_leaf.py @@ -2,1426 +2,303 @@ Module to provide tests related to the MD027 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import ( - assert_file_is_as_expected, - copy_to_temp_file, - create_temporary_configuration_file, +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, ) import pytest source_path = os.path.join("test", "resources", "rules", "md027") + os.sep - -@pytest.mark.rules -def test_md027_good_block_quote_atx_heading(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with an Atx Heading with the right amount of spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_atx_heading.md" - ) - supplied_arguments = [ - "--disable-rules", - "md022", - "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_md027_bad_block_quote_atx_heading(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an Atx Heading with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_atx_heading.md" - ) - supplied_arguments = [ - "--disable-rules", - "md022,md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_unordered_list_text_first_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_atx_heading.md" - ) as temp_source_path: - original_file_contents = """> this is text +__plugin_disable_md009 = "md009" +__plugin_disable_md022 = "md022" +__plugin_disable_md022_md023 = "md022,md023" +__plugin_disable_md023 = "md023" +__plugin_disable_md031 = "md031" + +scanTests = [ + pluginRuleTest( + "good_block_quote_atx_heading", + source_file_name=f"{source_path}good_block_quote_atx_heading.md", + disable_rules=__plugin_disable_md022, + ), + pluginRuleTest( + "bad_block_quote_atx_heading", + source_file_name=f"{source_path}bad_block_quote_atx_heading.md", + disable_rules=__plugin_disable_md022_md023, + source_file_contents="""> this is text > # New Heading -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md022,md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > # New Heading -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_setext_heading(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with an SetExt Heading with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_setext_heading.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_md027_bad_block_quote_setext_heading_first_line(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an SetExt Heading with extra spaces on the - first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_first_line.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_first_line_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_first_line.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_setext_heading", + source_file_name=f"{source_path}good_block_quote_setext_heading.md", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_first_line", + source_file_name=f"{source_path}bad_block_quote_setext_heading_first_line.md", + disable_rules=__plugin_disable_md023, + source_file_contents="""> this is text > > a setext heading > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > a setext heading > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_second_line(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an SetExt Heading with extra spaces on the - second line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_second_line.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_second_line_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_second_line.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_second_line", + source_file_name=f"{source_path}bad_block_quote_setext_heading_second_line.md", + disable_rules=__plugin_disable_md023, + source_file_contents="""> this is text > > a setext heading > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--stack-trace", - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > a setext heading > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_setext_heading_multiples(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with an SetExt Heading with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "good_block_quote_setext_heading_multiples.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_md027_bad_block_quote_setext_heading_multiples_first(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with an SetExt Heading with no spaces with - extra space on the first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_multiples_first.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_multiples_first_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_multiples_first.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_setext_heading_multiples", + source_file_name=f"{source_path}good_block_quote_setext_heading_multiples.md", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_multiples_first", + source_file_name=f"{source_path}bad_block_quote_setext_heading_multiples_first.md", + disable_rules=__plugin_disable_md023, + source_file_contents="""> this is text > > a setext heading > that is not properly > indented > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > a setext heading > that is not properly > indented > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_multiples_middle(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an SetExt Heading with no spaces with - extra space on one of the middle lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_multiples_middle.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_multiples_middle_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_multiples_middle.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_multiples_middle", + source_file_name=f"{source_path}bad_block_quote_setext_heading_multiples_middle.md", + disable_rules=__plugin_disable_md023, + source_file_contents="""> this is text > > a setext heading > that is not properly > indented > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > a setext heading > that is not properly > indented > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_multiples_last(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an SetExt Heading with no spaces with - extra space on the last line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_multiples_last.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_multiples_last_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_multiples_last.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_setext_heading_multiples_middle___X", + disable_rules=__plugin_disable_md009, + source_file_contents="""> this is text +> +> a setext heading\a +> that is not properly\a +> indented +> --- +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "bad_block_quote_setext_heading_multiples_last", + source_file_name=f"{source_path}bad_block_quote_setext_heading_multiples_last.md", + disable_rules=__plugin_disable_md023, + source_file_contents="""> this is text > > a setext heading > that is not properly > indented > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > a setext heading > that is not properly > indented > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_multiples_last_x(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with an SetExt Heading with no spaces with - extra space on the last line. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_multiples_last_x", + disable_rules=__plugin_disable_md023, + source_file_contents="""> this is text > > a setext heading > that is not properly > indented > --- -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{temp_source_path}:6:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_multiples_last_x_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """> this is text -> -> a setext heading -> that is not properly -> indented -> --- -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--stack-trace", - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:6:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > a setext heading > that is not properly > indented > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_thematic(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a Thematic Break with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_thematic.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_md027_bad_block_quote_thematic(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a Thematic Break with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_thematic.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_thematic_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_thematic.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_thematic", + source_file_name=f"{source_path}good_block_quote_thematic.md", + ), + pluginRuleTest( + "bad_block_quote_thematic", + source_file_contents="""> this is text > > ------ > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > ------ > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_html(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a HTML block with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_html.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_md027_good_block_quote_html_first(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a HTML block with extra spaces on the first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_html_first.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_md027_good_block_quote_html_middle(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a HTML block with extra spaces on one - of the middle lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_html_middle.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_md027_good_block_quote_html_last(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a HTML block with extra spaces on the last line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_html_last.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_md027_good_block_quote_fenced(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a fenced block with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_fenced.md" - ) - supplied_arguments = [ - "--disable-rules", - "md031", - "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_md027_good_block_quote_fenced_middle(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a fenced block with extra spaces in the middle. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_fenced_middle.md" - ) - supplied_arguments = [ - "--disable-rules", - "md031", - "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_md027_bad_block_quote_fenced_first(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a fenced block with extra spaces on the first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_fenced_first.md" - ) - supplied_arguments = [ - "--disable-rules", - "md031", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_fenced_first_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_fenced_first.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_html", + source_file_name=f"{source_path}good_block_quote_html.md", + ), + pluginRuleTest( + "good_block_quote_html_first", + source_file_name=f"{source_path}good_block_quote_html_first.md", + ), + pluginRuleTest( + "good_block_quote_html_middle", + source_file_name=f"{source_path}good_block_quote_html_middle.md", + ), + pluginRuleTest( + "good_block_quote_html_last", + source_file_name=f"{source_path}good_block_quote_html_last.md", + ), + pluginRuleTest( + "good_block_quote_fenced", + source_file_name=f"{source_path}good_block_quote_fenced.md", + disable_rules=__plugin_disable_md031, + ), + pluginRuleTest( + "good_block_quote_fenced_middle", + source_file_name=f"{source_path}good_block_quote_fenced_middle.md", + disable_rules=__plugin_disable_md031, + ), + pluginRuleTest( + "bad_block_quote_fenced_first", + source_file_name=f"{source_path}bad_block_quote_fenced_first.md", + disable_rules=__plugin_disable_md031, + source_file_contents="""> this is text > ```code > this is a fenced block > ``` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md031", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > ```code > this is a fenced block > ``` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_fenced_last(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a fenced block with extra spaces on the - last line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_fenced_last.md" - ) - supplied_arguments = [ - "--disable-rules", - "md031", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_fenced_last_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_fenced_last.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_fenced_last", + source_file_name=f"{source_path}bad_block_quote_fenced_last.md", + disable_rules=__plugin_disable_md031, + source_file_contents="""> this is text > ```code > this is a fenced block > ``` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md031", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > ```code > this is a fenced block > ``` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_indented(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a indented block with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_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 - ) - - -@pytest.mark.rules -def test_md027_good_block_quote_indented_first(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a indented block with extra spaces on - the first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_indented_first.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_md027_good_block_quote_indented_middle(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a indented block with extra spaces on - one of the middle lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_indented_middle.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_md027_good_block_quote_indented_last(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a indented block with extra spaces on - the last line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_indented_last.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_md027_good_block_quote_lrd(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a LRD with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_lrd.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_md027_good_block_quote_lrd_multiple(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a multiple line LRD with no spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_lrd_multiple.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_md027_bad_block_quote_lrd_multiple_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multiple line LRD with extra space on line 1. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_lrd_multiple_one.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_lrd_multiple_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_lrd_multiple_one.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_indented", + source_file_name=f"{source_path}good_block_quote_indented.md", + ), + pluginRuleTest( + "good_block_quote_indented_first", + source_file_name=f"{source_path}good_block_quote_indented_first.md", + ), + pluginRuleTest( + "good_block_quote_indented_middle", + source_file_name=f"{source_path}good_block_quote_indented_middle.md", + ), + pluginRuleTest( + "good_block_quote_indented_last", + source_file_name=f"{source_path}good_block_quote_indented_last.md", + ), + pluginRuleTest( + "good_block_quote_lrd", + source_file_name=f"{source_path}good_block_quote_lrd.md", + ), + pluginRuleTest( + "good_block_quote_lrd_multiple", + source_file_name=f"{source_path}good_block_quote_lrd_multiple.md", + ), + pluginRuleTest( + "bad_block_quote_lrd_multiple_one", + source_file_name=f"{source_path}bad_block_quote_lrd_multiple_one.md", + source_file_contents="""> this is text > > [lab > el]: @@ -1430,20 +307,11 @@ def test_md027_bad_block_quote_lrd_multiple_one_fix(): > le" > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > [lab > el]: @@ -1452,184 +320,38 @@ def test_md027_bad_block_quote_lrd_multiple_one_fix(): > le" > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_lrd_no_title(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multiple line LRD with extra space on line 1. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """> this is text -> -> [lab -> el]: -> /url -> -> a real test -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{temp_source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_lrd_no_title_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_lrd_no_title", + source_file_contents="""> this is text > > [lab > el]: > /url > > a real test -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > [lab > el]: > /url > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_lrd_multiple_two(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a multiple line LRD with extra space on line 2. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_lrd_multiple_two.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_md027_bad_block_quote_lrd_multiple_three(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multiple line LRD with extra space on line 3. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_lrd_multiple_three.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_lrd_multiple_three_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_lrd_multiple_three.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_lrd_multiple_two", + source_file_name=f"{source_path}good_block_quote_lrd_multiple_two.md", + ), + pluginRuleTest( + "bad_block_quote_lrd_multiple_three", + source_file_name=f"{source_path}bad_block_quote_lrd_multiple_three.md", + source_file_contents="""> this is text > > [lab > el]: @@ -1638,20 +360,11 @@ def test_md027_bad_block_quote_lrd_multiple_three_fix(): > le" > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > [lab > el]: @@ -1660,64 +373,12 @@ def test_md027_bad_block_quote_lrd_multiple_three_fix(): > le" > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_lrd_multiple_four(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multiple line LRD with extra space on line 4. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_lrd_multiple_four.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_lrd_multiple_four_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_lrd_multiple_four.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "bad_block_quote_lrd_multiple_four", + source_file_name=f"{source_path}bad_block_quote_lrd_multiple_four.md", + source_file_contents="""> this is text > > [lab > el]: @@ -1726,20 +387,11 @@ def test_md027_bad_block_quote_lrd_multiple_four_fix(): > le" > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:6:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > > [lab > el]: @@ -1748,100 +400,16 @@ def test_md027_bad_block_quote_lrd_multiple_four_fix(): > le" > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_good_block_quote_lrd_multiple_five(): - """ - Test to make sure this rule does not trigger with a document that - contains a block quote with a multiple line LRD with extra space on line 5. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "good_block_quote_lrd_multiple_five.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_md027_bad_block_quote_link_multiple_extra(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with a multiple line link with extra spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_link_multiple_extra.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:6:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)\n" - + f"{source_path}:7:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_link_multiple_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_link_multiple_extra.md" - ) as temp_source_path: - original_file_contents = """> this is text +""", + ), + pluginRuleTest( + "good_block_quote_lrd_multiple_five", + source_file_name=f"{source_path}good_block_quote_lrd_multiple_five.md", + ), + pluginRuleTest( + "bad_block_quote_link_multiple_extra", + source_file_name=f"{source_path}bad_block_quote_link_multiple_extra.md", + source_file_contents="""> this is text > [a not > so > simple](/link @@ -1849,20 +417,14 @@ def test_md027_bad_block_quote_link_multiple_extra_fix(): > title" > ) > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """> this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:6:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:7:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents="""> this is text > [a not > so > simple](/link @@ -1870,13 +432,26 @@ def test_md027_bad_block_quote_link_multiple_extra_fix(): > title" > ) > a real test -""" +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md027_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md027") - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md027_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) diff --git a/test/rules/test_md027_leaf_plus_one.py b/test/rules/test_md027_leaf_plus_one.py index 972448d82..f73f3f8e3 100644 --- a/test/rules/test_md027_leaf_plus_one.py +++ b/test/rules/test_md027_leaf_plus_one.py @@ -2,490 +2,115 @@ Module to provide tests related to the MD027 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, +) import pytest source_path = os.path.join("test", "resources", "rules", "md027") + os.sep -@pytest.mark.rules -def test_md027_bad_block_quote_atx_heading_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and an Atx Heading, which has - an extra space before it. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_atx_heading_plus_one.md" - ) - supplied_arguments = [ - "--disable-rules", - "md022,md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - +__plugin_disable_md022_md023 = "md022,md023" +__plugin_disable_md023 = "md023" +__plugin_disable_md031 = "md031" -@pytest.mark.rules -def test_md027_bad_block_quote_atx_heading_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_atx_heading_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +scanTests = [ + pluginRuleTest( + "bad_block_quote_atx_heading_plus_one", + source_file_name=f"{source_path}bad_block_quote_atx_heading_plus_one.md", + disable_rules=__plugin_disable_md022_md023, + source_file_contents=""" > this is text > # New Heading -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md022,md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > # New Heading -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_atx_heading_misaligned(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and an Atx Heading, which has - is aligned to the text, not the block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_atx_heading_misaligned.md", - ) - supplied_arguments = [ - "--disable-rules", - "md022,md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_atx_heading_misaligned_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_atx_heading_misaligned.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_atx_heading_misaligned", + source_file_name=f"{source_path}bad_block_quote_atx_heading_misaligned.md", + disable_rules=__plugin_disable_md022_md023, + source_file_contents=""" > this is text > # New Heading -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md022,md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > # New Heading -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_fenced_first_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a Fenced code block with - an extra space before the start. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_fenced_first_plus_one.md", - ) - supplied_arguments = [ - "--disable-rules", - "md031", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_fenced_first_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_fenced_first_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_fenced_first_plus_one", + source_file_name=f"{source_path}bad_block_quote_fenced_first_plus_one.md", + disable_rules=__plugin_disable_md031, + source_file_contents=""" > this is text > ```code > this is a fenced block > ``` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md031", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > ```code > this is a fenced block > ``` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_fenced_last_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a Fenced code block with - an extra space before the end. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_fenced_last_plus_one.md" - ) - supplied_arguments = [ - "--disable-rules", - "md031", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_fenced_last_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_fenced_last_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_fenced_last_plus_one", + source_file_name=f"{source_path}bad_block_quote_fenced_last_plus_one.md", + disable_rules=__plugin_disable_md031, + source_file_contents=""" > this is text > ```code > this is a fenced block > ``` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md031", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > ```code > this is a fenced block > ``` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_fenced_last_misaligned(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a Fenced code block with - an extra space before the end, in misalligned block quotes. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_fenced_last_misaligned.md", - ) - supplied_arguments = [ - "--disable-rules", - "md031", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_fenced_last_misaligned_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_fenced_last_misaligned.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_fenced_last_misaligned", + source_file_name=f"{source_path}bad_block_quote_fenced_last_misaligned.md", + disable_rules=__plugin_disable_md031, + source_file_contents=""" > this is text > ```code > this is a fenced block > ``` > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md031", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > ```code > this is a fenced block > ``` > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_lrd_multiple_one_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a LRD that has extr soace - before line 1. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_lrd_multiple_one_plus_one.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_lrd_multiple_one_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_lrd_multiple_one_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_lrd_multiple_one_plus_one", + source_file_name=f"{source_path}bad_block_quote_lrd_multiple_one_plus_one.md", + source_file_contents=""" > this is text > > [lab > el]: @@ -494,20 +119,11 @@ def test_md027_bad_block_quote_lrd_multiple_one_plus_one_fix(): > le" > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > [lab > el]: @@ -516,69 +132,12 @@ def test_md027_bad_block_quote_lrd_multiple_one_plus_one_fix(): > le" > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_lrd_multiple_three_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a LRD that has extr soace - before line 3. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_lrd_multiple_three_plus_one.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_lrd_multiple_three_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_lrd_multiple_three_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_lrd_multiple_three_plus_one", + source_file_name=f"{source_path}bad_block_quote_lrd_multiple_three_plus_one.md", + source_file_contents=""" > this is text > > [lab > el]: @@ -587,20 +146,11 @@ def test_md027_bad_block_quote_lrd_multiple_three_plus_one_fix(): > le" > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > [lab > el]: @@ -609,69 +159,12 @@ def test_md027_bad_block_quote_lrd_multiple_three_plus_one_fix(): > le" > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_lrd_multiple_three_misaligned(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a LRD that has extr soace - before line 3, misaligned. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_lrd_multiple_three_misaligned.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_lrd_multiple_three_misaligned_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_lrd_multiple_three_misaligned.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_lrd_multiple_three_misaligned", + source_file_name=f"{source_path}bad_block_quote_lrd_multiple_three_misaligned.md", + source_file_contents=""" > this is text > > [lab > el]: @@ -680,20 +173,11 @@ def test_md027_bad_block_quote_lrd_multiple_three_misaligned_fix(): > le" > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > [lab > el]: @@ -702,69 +186,12 @@ def test_md027_bad_block_quote_lrd_multiple_three_misaligned_fix(): > le" > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_lrd_multiple_four_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a LRD that has extr soace - before line 4. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_lrd_multiple_four_plus_one.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_lrd_multiple_four_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_lrd_multiple_four_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_lrd_multiple_four_plus_one", + source_file_name=f"{source_path}bad_block_quote_lrd_multiple_four_plus_one.md", + source_file_contents=""" > this is text > > [lab > el]: @@ -773,20 +200,11 @@ def test_md027_bad_block_quote_lrd_multiple_four_plus_one_fix(): > le" > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:6:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > [lab > el]: @@ -795,895 +213,236 @@ def test_md027_bad_block_quote_lrd_multiple_four_plus_one_fix(): > le" > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_lrd_multiple_four_misaligned(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a LRD that has extr soace - before line 4, misaligned. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_lrd_multiple_four_misaligned.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_lrd_multiple_four_misaligned_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_lrd_multiple_four_misaligned.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_lrd_multiple_four_misaligned", + source_file_name=f"{source_path}bad_block_quote_lrd_multiple_four_plus_one.md", + source_file_contents=""" > this is text > > [lab > el]: > /url -> "tit -> le" -> -> a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text + > "tit + > le" + > + > a real test +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:6:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > [lab > el]: > /url -> "tit -> le" -> -> a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_thematic_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with text and a thematic break with extra. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md027", "bad_block_quote_thematic_plus_one.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_thematic_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_thematic_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text + > "tit + > le" + > + > a real test +""", + ), + pluginRuleTest( + "bad_block_quote_thematic_plus_one", + source_file_name=f"{source_path}bad_block_quote_thematic_plus_one.md", + source_file_contents=""" > this is text > > ------ > > a real test -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > ------ > > a real test -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_first_line_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with SetExt with extra space in first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_first_line_plus_one.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_first_line_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_first_line_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_first_line_plus_one", + source_file_name=f"{source_path}bad_block_quote_setext_heading_first_line_plus_one.md", + disable_rules=__plugin_disable_md023, + source_file_contents=""" > this is text > > a setext heading > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > a setext heading > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_multiples_first_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with SetExt with extra space in first line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_multiples_first_plus_one.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_multiples_first_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_multiples_first_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_multiples_first_plus_one", + source_file_name=f"{source_path}bad_block_quote_setext_heading_multiples_first_plus_one.md", + disable_rules=__plugin_disable_md023, + source_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_multiples_middle_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with SetExt with extra space in middle line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_multiples_middle_plus_one.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_multiples_middle_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_multiples_middle_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_multiples_middle_plus_one", + source_file_name=f"{source_path}bad_block_quote_setext_heading_multiples_middle_plus_one.md", + disable_rules=__plugin_disable_md023, + source_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_multiples_middle_misaligned(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with SetExt with extra space in middle line, - with misaligned block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_multiples_middle_misaligned.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_multiples_middle_misaligned_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_multiples_middle_misaligned.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_multiples_middle_misaligned", + source_file_name=f"{source_path}bad_block_quote_setext_heading_multiples_middle_misaligned.md", + disable_rules=__plugin_disable_md023, + source_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_multiples_last_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with SetExt with extra space in last line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_multiples_last_plus_one.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_multiples_last_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_multiples_last_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_multiples_last_plus_one", + source_file_name=f"{source_path}bad_block_quote_setext_heading_multiples_last_plus_one.md", + disable_rules=__plugin_disable_md023, + source_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_multiples_last_misaligned(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with SetExt with extra space in last line, misaligned. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_multiples_last_misaligned.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_multiples_last_misaligned_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_multiples_last_misaligned.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_multiples_last_misaligned", + source_file_name=f"{source_path}bad_block_quote_setext_heading_multiples_last_misaligned.md", + disable_rules=__plugin_disable_md023, + source_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > a setext heading > that is not properly > indented > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_second_line_plus_one(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with SetExt with extra space in second line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_second_line_plus_one.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:4: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_second_line_plus_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_second_line_plus_one.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_second_line_plus_one", + source_file_name=f"{source_path}bad_block_quote_setext_heading_second_line_plus_one.md", + disable_rules=__plugin_disable_md023, + source_file_contents=""" > this is text > > a setext heading > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:4: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > a setext heading > --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md027_bad_block_quote_setext_heading_second_line_misaligned(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with SetExt with extra space in second line, misaligned. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md027", - "bad_block_quote_setext_heading_second_line_misaligned.md", - ) - supplied_arguments = [ - "--disable-rules", - "md023", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:3: " - + "MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote)" - ) - 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_md027_bad_block_quote_setext_heading_second_line_misaligned_fix(): - """ - Test to make sure this rule does trigger with a document that - contains a block quote with more than 1 space after it. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_block_quote_setext_heading_second_line_misaligned.md" - ) as temp_source_path: - original_file_contents = """ > this is text +""", + ), + pluginRuleTest( + "bad_block_quote_setext_heading_second_line_misaligned", + source_file_name=f"{source_path}bad_block_quote_setext_heading_second_line_misaligned.md", + disable_rules=__plugin_disable_md023, + source_file_contents=""" > this is text > > a setext heading > --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md023", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """ > this is text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +""", + fix_expected_file_contents=""" > this is text > > a setext heading > --- -""" +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md027_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md027") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md027_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) diff --git a/test/rules/test_md029.py b/test/rules/test_md029.py index c66fefc14..463940348 100644 --- a/test/rules/test_md029.py +++ b/test/rules/test_md029.py @@ -2,11 +2,13 @@ Module to provide tests related to the MD029 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import ( - assert_file_is_as_expected, - copy_to_temp_file, - create_temporary_configuration_file, +from test.rules.utils import ( + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, ) import pytest @@ -15,555 +17,121 @@ source_path = os.path.join("test", "resources", "rules", "md029") + os.sep - -@pytest.mark.rules -def test_md029_bad_configuration_style(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with an integer that is not a string. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=$#1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md029.style' must be of type 'str'." - ) - - # 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_md029_bad_configuration_style_invalid(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with a string that is not valid. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=not-matching", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md029.style' is not valid: Allowable values: ['one', 'ordered', 'zero', 'one_or_ordered']" - ) - - # 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_md029_good_one_list(): - """ - Test to make sure this rule does not trigger with a document that - contains ordered lists that only have number 1. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_list.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_md029_bad_one_one_three_list(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have numbers 1 and 3. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_one_one_three_list.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 3; Style: 1/1/1] (ol-prefix)" - ) - 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_md029_bad_one_one_three_list_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have numbers 1 and 3. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_one_one_three_list.md" - ) as temp_source_path: - original_file_contents = """1. Simple +__plugin_disable_md007 = "md007" + +configTests = [ + pluginConfigErrorTest( + "invalid_style_type", + use_strict_config=True, + set_args=["plugins.md029.style=$#1"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md029.style' must be of type 'str'.""", + ), + pluginConfigErrorTest( + "invalid_style", + use_strict_config=True, + set_args=["plugins.md029.style=not-matching"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md029.style' is not valid: Allowable values: ['one', 'ordered', 'zero', 'one_or_ordered']""", + ), +] + +scanTests = [ + pluginRuleTest( + "good_one_list", + source_file_name=f"{source_path}good_one_list.md", + ), + pluginRuleTest( + "bad_one_one_three_list", + source_file_name=f"{source_path}bad_one_one_three_list.md", + source_file_contents="""1. Simple 1. One 3. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:1: MD029: Ordered list item prefix [Expected: 1; Actual: 3; Style: 1/1/1] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 1. One 1. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_bad_one_two_one_list(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have numbers 1 and 2. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_one_two_one_list.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 3; Actual: 1; Style: 1/2/3] (ol-prefix)" - ) - 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_md029_bad_one_two_one_list_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have numbers 1 and 2. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_one_two_one_list.md") as temp_source_path: - original_file_contents = """1. Simple +""", + ), + pluginRuleTest( + "bad_one_two_one_list", + source_file_name=f"{source_path}bad_one_two_one_list.md", + source_file_contents="""1. Simple 2. One 1. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:1: MD029: Ordered list item prefix [Expected: 3; Actual: 1; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 2. One 3. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_good_one_two_three_list(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have numbers 1, 2, and 3. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_two_three_list.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_md029_bad_two_three_four_list(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have numbers 2 to 4. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_two_three_four_list.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 2; Style: 1/2/3] (ol-prefix)" - ) - 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_md029_bad_two_three_four_list_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have numbers 1 and 2. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_two_three_four_list.md" - ) as temp_source_path: - original_file_contents = """2. Simple +""", + ), + pluginRuleTest( + "good_one_two_three_list", + source_file_name=f"{source_path}good_one_two_three_list.md", + ), + pluginRuleTest( + "bad_two_three_four_list", + source_file_name=f"{source_path}bad_two_three_four_list.md", + source_file_contents="""2. Simple 3. One 4. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 2. One 3. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_bad_nested_lists_1_with_no_config(): - """ - Test to make sure this rule does trigger... - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """2. first +""", + ), + pluginRuleTest( + "bad_nested_lists_1_with_no_config", + source_file_contents="""2. first 1. first-first 1. first-second - 2. first-third 3. second 1. second-first 2. second-second - 2. second-third -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--strict-config", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/2/3] (ol-prefix) -{path}:4:4: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix) -{path}:8:4: MD029: Ordered list item prefix [Expected: 3; Actual: 2; Style: 1/2/3] (ol-prefix)""".replace( - "{path}", temp_source_path - ) - 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_md029_bad_nested_lists_1_with_no_config_fix(): - """ - Test to make sure this rule does trigger - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """2. first - 1. first-first - 1. first-second -3. second - 1. second-first - 2. second-second -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. first +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. first 1. first-first 1. first-second 2. second 1. second-first 2. second-second -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_bad_nested_lists_2_with_no_config(): - """ - Test to make sure this rule does trigger... - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """0. first - 1. first-first - 31. first-second -3. second - 1. second-first -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--strict-config", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:3:4: MD029: Ordered list item prefix [Expected: 2; Actual: 31; Style: 1/2/3] (ol-prefix) -{path}:4:1: MD029: Ordered list item prefix [Expected: 1; Actual: 3; Style: 1/2/3] (ol-prefix)""".replace( - "{path}", temp_source_path - ) - 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_md029_bad_nested_lists_2_with_no_config_fix(): - """ - Test to make sure this rule does trigger - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """0. first +""", + ), + pluginRuleTest( + "bad_nested_lists_2_with_no_config", + source_file_contents="""0. first 1. first-first 31. first-second 3. second 1. second-first -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """0. first +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:4: MD029: Ordered list item prefix [Expected: 2; Actual: 31; Style: 1/2/3] (ol-prefix) +{temp_source_path}:4:1: MD029: Ordered list item prefix [Expected: 1; Actual: 3; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""0. first 1. first-first 2. first-second 1. second 1. second-first -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_good_nested_lists_3_with_no_config(): - """ - Test to make sure this rule does trigger... - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """1. First Line +""", + ), + pluginRuleTest( + "good_nested_lists_3_with_no_config", + source_file_contents="""1. First Line 1. Second Line text to break up lists @@ -571,1607 +139,468 @@ def test_md029_good_nested_lists_3_with_no_config(): 1. First Item 2. Second Item 3. Third Item -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--strict-config", - "scan", - temp_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_md029_good_zero_one_two_three_list(): - """ - Test to make sure this rule does not trigger with a document that - contains ordered lists that have numbers 0 to 3. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_zero_one_two_three_list.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_md029_bad__lists_1_with_no_config(): - """ - Test to make sure this rule does trigger... - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """3. first -3. second -3. third -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--strict-config", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 3; Style: 1/2/3] (ol-prefix)""".replace( - "{path}", temp_source_path - ) - 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_md029_bad__lists_1_with_no_config_fix(): - """ - Test to make sure this rule does trigger - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """3. first +""", + ), + pluginRuleTest( + "good_zero_one_two_three_list", + source_file_name=f"{source_path}good_zero_one_two_three_list.md", + ), + pluginRuleTest( + "bad_lists_1_with_no_config", + source_file_contents="""3. first 3. second 3. third -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. first +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 3; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. first 2. second 3. third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_good_zero_list(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that only have number 0. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_zero_list.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 0; Style: 1/2/3] (ol-prefix)" - ) - 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_md029_good_one_list_with_config_one(): - """ - Test to make sure this rule does not trigger with a document that - contains ordered lists that only have number 1 and matching configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--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_md029_bad_one_one_three_list_with_config_one(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_one_one_three_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 3; Style: 1/1/1] (ol-prefix)" - ) - 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_md029_bad_one_one_three_list_with_config_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_one_one_three_list.md" - ) as temp_source_path: - original_file_contents = """1. Simple +""", + ), + pluginRuleTest( + "bad_zero_list", + source_file_name=f"{source_path}good_zero_list.md", + source_file_contents="""0. Simple +0. One +0. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD029: Ordered list item prefix [Expected: 1; Actual: 0; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""0. Simple +1. One +2. List +""", + ), + pluginRuleTest( + "good_one_list_with_config_one", + source_file_name=f"{source_path}good_one_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=one"], + ), + pluginRuleTest( + "bad_one_one_three_list_with_config_one", + source_file_name=f"{source_path}bad_one_one_three_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=one"], + source_file_contents="""1. Simple 1. One 3. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:1: MD029: Ordered list item prefix [Expected: 1; Actual: 3; Style: 1/1/1] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 1. One 1. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_bad_one_two_one_list_with_config_one(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 2 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_one_two_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix)" - ) - 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_md029_bad_one_two_one_list_with_config_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_one_two_one_list.md") as temp_source_path: - original_file_contents = """1. Simple +""", + ), + pluginRuleTest( + "bad_one_two_one_list_with_config_one", + source_file_name=f"{source_path}bad_one_two_one_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=one"], + source_file_contents="""1. Simple 2. One 1. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 1. One 1. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_good_one_two_three_list_with_config_one(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1, 2, 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_two_three_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix)" - ) - 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_md029_bad_two_three_four_list_with_config_one(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 2 to 4 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_two_three_four_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix)" - ) - 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_md029_bad_two_three_four_list_with_config_one_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_two_three_four_list.md" - ) as temp_source_path: - original_file_contents = """2. Simple +""", + ), + pluginRuleTest( + "bad_one_two_three_list_with_config_one", + source_file_name=f"{source_path}bad_one_two_one_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=one"], + source_file_contents="""1. Simple +2. One +1. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple +1. One +1. List +""", + ), + pluginRuleTest( + "bad_two_three_four_list_with_config_one", + source_file_name=f"{source_path}bad_two_three_four_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=one"], + source_file_contents="""2. Simple 3. One 4. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 1. One 1. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_bad_nested_lists_with_config_one(): - """ - Test to make sure this rule does trigger... - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """2. first - 1. first-first - 2. first-second -3. second - 1. second-first -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix) -{path}:3:4: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix)""".replace( - "{path}", temp_source_path - ) - 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_md029_bad_nested_lists_with_config_one_fix(): - """ - Test to make sure this rule does trigger - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """2. first +""", + ), + pluginRuleTest( + "bad_nested_lists_with_config_one", + use_strict_config=True, + set_args=["plugins.md029.style=one"], + source_file_contents="""2. first 1. first-first 2. first-second 3. second 1. second-first -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. first +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix) +{temp_source_path}:3:4: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/1/1] (ol-prefix) +""", + fix_expected_file_contents="""1. first 1. first-first 1. first-second 1. second 1. second-first -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_good_zero_one_two_list_with_config_one(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 0 to 2 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_zero_one_two_three_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 0; Style: 1/1/1] (ol-prefix)" - ) - 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_md029_good_zero_list_with_config_one(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have only number 0 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_zero_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=one", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 0; Style: 1/1/1] (ol-prefix)" - ) - 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_md029_good_one_list_with_config_ordered(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and `ordered` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 2; Actual: 1; Style: 1/2/3] (ol-prefix)" - ) - 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_md029_bad_one_one_three_list_with_config_ordered(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `ordered` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_one_one_three_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 2; Actual: 1; Style: 1/2/3] (ol-prefix)" - ) - 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_md029_bad_one_one_three_list_with_config_ordered_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_one_one_three_list.md" - ) as temp_source_path: - original_file_contents = """1. Simple +""", + ), + pluginRuleTest( + "bad_zero_one_two_list_with_config_one", + source_file_name=f"{source_path}good_zero_one_two_three_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=one"], + source_file_contents="""0. Simple +1. One +2. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 0; Style: 1/1/1] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 1. One +1. List +""", + ), + pluginRuleTest( + "bad_zero_list_with_config_one", + source_file_name=f"{source_path}good_zero_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=one"], + source_file_contents="""0. Simple +0. One +0. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 0; Style: 1/1/1] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple +1. One +1. List +""", + ), + pluginRuleTest( + "bad_one_list_with_config_ordered", + source_file_name=f"{source_path}good_one_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=ordered"], + source_file_contents="""1. Simple +1. One +1. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD029: Ordered list item prefix [Expected: 2; Actual: 1; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple +2. One 3. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Simple +""", + ), + pluginRuleTest( + "bad_one_one_three_list_with_config_ordered", + source_file_name=f"{source_path}bad_one_one_three_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=ordered"], + source_file_contents="""1. Simple +1. One +3. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD029: Ordered list item prefix [Expected: 2; Actual: 1; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 2. One 3. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_bad_one_two_one_list_with_config_ordered(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 2 and `ordered` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_one_two_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 3; Actual: 1; Style: 1/2/3] (ol-prefix)" - ) - 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_md029_bad_one_two_one_list_with_config_ordered_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_one_two_one_list.md") as temp_source_path: - original_file_contents = """1. Simple +""", + ), + pluginRuleTest( + "bad_one_two_one_list_with_config_ordered", + source_file_name=f"{source_path}bad_one_two_one_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=ordered"], + source_file_contents="""1. Simple 2. One 1. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:1: MD029: Ordered list item prefix [Expected: 3; Actual: 1; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 2. One 3. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_good_one_two_three_list_with_config_ordered(): - """ - Test to make sure this rule does not trigger with a document that - contains ordered lists that have number 1 to 3 and `ordered` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_two_three_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--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_md029_bad_two_three_four_list_with_config_ordered(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 2 to 4 and `ordered` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_two_three_four_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 2; Style: 1/2/3] (ol-prefix)" - ) - 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_md029_bad_two_three_four_list_with_config_ordered_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_two_three_four_list.md" - ) as temp_source_path: - original_file_contents = """2. Simple +""", + ), + pluginRuleTest( + "good_one_two_three_list_with_config_ordered", + source_file_name=f"{source_path}good_one_two_three_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=ordered"], + ), + pluginRuleTest( + "bad_two_three_four_list_with_config_ordered", + source_file_name=f"{source_path}bad_two_three_four_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=ordered"], + source_file_contents="""2. Simple 3. One 4. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. Simple 2. One 3. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_bad_nested_lists_with_config_ordered(): - """ - Test to make sure this rule does trigger... - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """2. first - 1. first-first - 1. first-second -3. second - 1. second-first -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/2/3] (ol-prefix) -{path}:3:4: MD029: Ordered list item prefix [Expected: 2; Actual: 1; Style: 1/2/3] (ol-prefix)""".replace( - "{path}", temp_source_path - ) - 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_md029_bad_nested_lists_with_config_ordered_fix(): - """ - Test to make sure this rule does trigger - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """2. first +""", + ), + pluginRuleTest( + "bad_nested_lists_with_config_ordered", + use_strict_config=True, + set_args=["plugins.md029.style=ordered"], + source_file_contents="""2. first 1. first-first 1. first-second 3. second 1. second-first -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. first +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/2/3] (ol-prefix) +{temp_source_path}:3:4: MD029: Ordered list item prefix [Expected: 2; Actual: 1; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. first 1. first-first 2. first-second 2. second 1. second-first -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_good_zero_one_two_list_with_config_ordered(): - """ - Test to make sure this rule does not trigger with a document that - contains ordered lists that have number 0 to 3 and `ordered` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_zero_one_two_three_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--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_md029_good_zero_list_with_config_ordered(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 0 and `ordered` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_zero_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=ordered", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 1; Actual: 0; Style: 1/2/3] (ol-prefix)" - ) - 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_md029_good_one_list_with_config_zero(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and `zero` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix)" - ) - 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_md029_bad_one_one_three_list_with_config_zero(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `zero` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_one_one_three_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix)" - ) - 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_md029_bad_one_one_three_list_with_config_zero_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_one_one_three_list.md" - ) as temp_source_path: - original_file_contents = """1. Simple +""", + ), + pluginRuleTest( + "good_zero_one_two_list_with_config_ordered", + source_file_name=f"{source_path}good_zero_one_two_three_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=ordered"], + source_file_contents="""0. Simple +1. One +2. List +""", + ), + pluginRuleTest( + "bad_zero_list_with_config_ordered", + source_file_name=f"{source_path}good_zero_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=ordered"], + source_file_contents="""0. Simple +0. One +0. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD029: Ordered list item prefix [Expected: 1; Actual: 0; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""0. Simple +1. One +2. List +""", + ), + pluginRuleTest( + "bad_one_list_with_config_zero", + source_file_name=f"{source_path}good_one_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=zero"], + source_file_contents="""1. Simple +1. One +1. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix) +""", + fix_expected_file_contents="""0. Simple +0. One +0. List +""", + ), + pluginRuleTest( + "bad_one_one_three_list_with_config_zero", + source_file_name=f"{source_path}bad_one_one_three_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=zero"], + source_file_contents="""1. Simple 1. One 3. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """0. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix) +""", + fix_expected_file_contents="""0. Simple 0. One 0. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_bad_one_two_one_list_with_config_zero(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 2 and `zero` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_one_two_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix)" - ) - 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_md029_bad_one_two_one_list_with_config_zero_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_one_two_one_list.md") as temp_source_path: - original_file_contents = """1. Simple +""", + ), + pluginRuleTest( + "bad_one_two_one_list_with_config_zero", + source_file_name=f"{source_path}bad_one_two_one_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=zero"], + source_file_contents="""1. Simple 2. One 1. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """0. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix) +""", + fix_expected_file_contents="""0. Simple 0. One 0. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_good_one_two_three_list_with_config_zero(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 to 3 and `zero` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_one_two_three_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix)" - ) - 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_md029_bad_two_three_four_list_with_config_zero(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 2 to 4 and `zero` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "bad_two_three_four_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 0; Actual: 2; Style: 0/0/0] (ol-prefix)" - ) - 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_md029_bad_two_three_four_list_with_config_zero_fix(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 1 and 3 and `one` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_two_three_four_list.md" - ) as temp_source_path: - original_file_contents = """2. Simple +""", + ), + pluginRuleTest( + "bad_one_two_three_list_with_config_zero", + source_file_name=f"{source_path}good_one_two_three_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=zero"], + source_file_contents="""1. Simple +2. One +3. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix) +""", + fix_expected_file_contents="""0. Simple +0. One +0. List +""", + ), + pluginRuleTest( + "bad_two_three_four_list_with_config_zero", + source_file_name=f"{source_path}bad_two_three_four_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=zero"], + source_file_contents="""2. Simple 3. One 4. List -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """0. Simple +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 0; Actual: 2; Style: 0/0/0] (ol-prefix) +""", + fix_expected_file_contents="""0. Simple 0. One 0. List -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_bad_nested_lists_with_config_zero(): - """ - Test to make sure this rule does trigger... - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """2. first +""", + ), + pluginRuleTest( + "bad_nested_lists_with_config_zero", + use_strict_config=True, + set_args=["plugins.md029.style=zero"], + source_file_contents="""2. first 1. first-first 2. first-second 3. second 1. second-first -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = """{path}:1:1: MD029: Ordered list item prefix [Expected: 0; Actual: 2; Style: 0/0/0] (ol-prefix) -{path}:2:4: MD029: Ordered list item prefix [Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix) -{path}:5:4: MD029: Ordered list item prefix [Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix)""".replace( - "{path}", temp_source_path - ) - 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_md029_bad_nested_lists_with_config_zero_fix(): - """ - Test to make sure this rule does trigger - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """2. first - 1. first-first - 2. first-second -3. second - 1. second-first -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """0. first +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD029: Ordered list item prefix [Expected: 0; Actual: 2; Style: 0/0/0] (ol-prefix) +{temp_source_path}:2:4: MD029: Ordered list item prefix [Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix) +{temp_source_path}:5:4: MD029: Ordered list item prefix [Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix) +""", + fix_expected_file_contents="""0. first 0. first-first 0. first-second 0. second 0. second-first -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md029_good_zero_one_two_list_with_config_zero(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists that have number 0 to 2 and `zero` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_zero_one_two_three_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD029: Ordered list item prefix " - + "[Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix)" - ) - 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_md029_good_zero_list_with_config_zero(): - """ - Test to make sure this rule does not trigger with a document that - contains ordered lists that have number 0 and `zero` configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md029", "good_zero_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md029.style=zero", - "--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 - ) +""", + ), + pluginRuleTest( + "bad_zero_one_two_list_with_config_zero", + source_file_name=f"{source_path}good_zero_one_two_three_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=zero"], + source_file_contents="""0. Simple +1. One +2. List +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD029: Ordered list item prefix [Expected: 0; Actual: 1; Style: 0/0/0] (ol-prefix) +""", + fix_expected_file_contents="""0. Simple +0. One +0. List +""", + ), + pluginRuleTest( + "good_zero_list_with_config_zero", + source_file_name=f"{source_path}good_zero_list.md", + use_strict_config=True, + set_args=["plugins.md029.style=zero"], + ), + pluginRuleTest( + "mix_md005_md029", + source_file_contents="""1. Heading 1 + 9. Heading 2 + 1. Heading 2 + 9. Heading 2 +""", + disable_rules=__plugin_disable_md007, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:2: MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 1] (list-indent) +{temp_source_path}:2:2: MD029: Ordered list item prefix [Expected: 2; Actual: 9; Style: 1/2/3] (ol-prefix) +{temp_source_path}:4:6: MD005: Inconsistent indentation for list items at the same level [Expected: 4; Actual: 5] (list-indent) +{temp_source_path}:4:6: MD029: Ordered list item prefix [Expected: 2; Actual: 9; Style: 1/2/3] (ol-prefix) +""", + fix_expected_file_contents="""1. Heading 1 +2. Heading 2 + 1. Heading 2 + 2. Heading 2 +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md029_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md029") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md029_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) + + +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md029_config(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_configuration_test(test, f"{source_path}good_one_list.md") diff --git a/test/rules/test_md030_ordered.py b/test/rules/test_md030_ordered.py index 59bda1520..2c4c2b3f0 100644 --- a/test/rules/test_md030_ordered.py +++ b/test/rules/test_md030_ordered.py @@ -2,8 +2,15 @@ Module to provide tests related to the MD030 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + build_fix_and_clash_lists, + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, +) import pytest @@ -12,1452 +19,337 @@ source_path = os.path.join("test", "resources", "rules", "md030") + os.sep -@pytest.mark.rules -def test_md030_bad_configuration_ol_single(): - """ - Test to verify that a configuration error is thrown when supplying the - ol_single value with a string that is not an integer. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=not-integer", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md030.ol_single' must be of type 'int'." - ) - - # 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_md030_bad_configuration_ol_single_zero(): - """ - Test to verify that a configuration error is thrown when supplying the - ol_single value with an integer not greater than 0. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#0", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md030.ol_single' is not valid: Allowable values are any integer greater than 0." - ) - - # 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_md030_bad_configuration_ol_multi(): - """ - Test to verify that a configuration error is thrown when supplying the - ol_multi value with a string that is not an integer. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_multi=not-integer", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md030.ol_multi' must be of type 'int'." - ) - - # 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_md030_bad_configuration_ol_multi_zero(): - """ - Test to verify that a configuration error is thrown when supplying the - ol_multi value with an integer not greater than 0. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_multi=$#0", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md030.ol_multi' is not valid: Allowable values are any integer greater than 0." - ) - - # 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_md030_good_spacing_ol_single_x(): - """ - Test to make sure this rule does not trigger with a document that - contains ordered lists with a single space after the marker. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ol_single.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_md030_good_spacing_ol_single_with_config_1_2(): - """ - Test to make sure this rule does not trigger with a document that - contains ordered lists with a single space after the marker, - with configuration. ul_multi does not come into effect as all - lines are single - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ol_single.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#1", - "--set", - "plugins.md030.ol_multi=$#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_md030_good_spacing_ol_single_with_config_2_1(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ol_single.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)\n" - + f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)\n" - + f"{source_path}:3:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)" - ) - 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_md030_good_spacing_ol_single_with_config_2_1_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_spacing_ol_single.md" - ) as temp_source_path: - original_file_contents = """1. First +configTests = [ + pluginConfigErrorTest( + "ol_single_type", + use_strict_config=True, + set_args=["plugins.md030.ol_single=not-integer"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md030.ol_single' must be of type 'int'.""", + ), + pluginConfigErrorTest( + "ol_single_range", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#0"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md030.ol_single' is not valid: Allowable values are any integer greater than 0.""", + ), + pluginConfigErrorTest( + "ol_multi_type", + use_strict_config=True, + set_args=["plugins.md030.ol_multi=not-integer"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md030.ol_multi' must be of type 'int'.""", + ), + pluginConfigErrorTest( + "ol_multi_range", + use_strict_config=True, + set_args=["plugins.md030.ol_multi=$#0"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md030.ol_multi' is not valid: Allowable values are any integer greater than 0.""", + ), +] + +scanTests = [ + pluginRuleTest( + "good_spacing_ol_single_x", + source_file_name=f"{source_path}good_spacing_ol_single.md", + ), + pluginRuleTest( + "test_md030_good_spacing_ol_single_with_config_1_2", + source_file_name=f"{source_path}good_spacing_ol_single.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#1", "plugins.md030.ol_multi=$#2"], + ), + pluginRuleTest( + "bad_spacing_ol_single_with_config_2_1", + source_file_name=f"{source_path}good_spacing_ol_single.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#2", "plugins.md030.ol_multi=$#1"], + source_file_contents="""1. First 1. Second 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +{temp_source_path}:3:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +""", + fix_expected_file_contents="""1. First 1. Second 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ol_single(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists with two spaces after the marker. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ol_single.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:3:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ol_single_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ol_single.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "bad_spacing_ol_single", + source_file_name=f"{source_path}bad_spacing_ol_single.md", + source_file_contents="""1. First 1. Second 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""1. First 1. Second 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ol_single_config_1_2(): - """ - Test to make sure this rule does trigger with a document that - contains ordered lists with two spaces after the marker and - configuration for multi line lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ol_single.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#1", - "--set", - "plugins.md030.ol_multi=$#2", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:3:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ol_single_config_1_2_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ol_single.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "bad_spacing_ol_single_config_1_2", + source_file_name=f"{source_path}bad_spacing_ol_single.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#1", "plugins.md030.ol_multi=$#2"], + source_file_contents="""1. First 1. Second 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#1", - "--set", - "plugins.md030.ol_multi=$#2", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""1. First 1. Second 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ol_single_config_2_1(): - """ - Test to make sure this rule does not trigger with a document that - contains ordered lists with two spaces after the marker, - and configuration to make it okay. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ol_single.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "--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_md030_good_spacing_ol_double(): - """ - Test to make sure this rule does not trigger with a document that - contains nested ordered lists with one space after the marker. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ol_double.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_md030_good_spacing_ol_double_config_1_2(): - """ - Test to make sure this rule does trigger with a document that - contains nested ordered lists with one space after the marker, - and configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ol_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#1", - "--set", - "plugins.md030.ol_multi=$#2", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)\n" - ) - 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_md030_good_spacing_ol_double_config_1_2_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_spacing_ol_double.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "bad_spacing_ol_single_config_2_1", + source_file_name=f"{source_path}bad_spacing_ol_single.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#2", "plugins.md030.ol_multi=$#1"], + ), + pluginRuleTest( + "good_spacing_ol_double", + source_file_name=f"{source_path}good_spacing_ol_double.md", + ), + pluginRuleTest( + "bad_spacing_ol_double_config_1_2", + source_file_name=f"{source_path}good_spacing_ol_double.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#1", "plugins.md030.ol_multi=$#2"], + source_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#1", - "--set", - "plugins.md030.ol_multi=$#2", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +""", + fix_expected_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_good_spacing_ol_double_config_2_1(): - """ - Test to make sure this rule does trigger with a document that - contains nested ordered lists with one space after the marker, - and configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ol_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)\n" - + f"{source_path}:5:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)" - ) - 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_md030_good_spacing_ol_double_config_2_1_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_spacing_ol_double.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "bad_spacing_ol_double_config_2_1", + source_file_name=f"{source_path}good_spacing_ol_double.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#2", "plugins.md030.ol_multi=$#1"], + source_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +""", + fix_expected_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ol_double(): - """ - Test to make sure this rule does trigger with a document that - contains nested ordered lists with two space after the marker. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ol_double.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:5:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ol_double_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ol_double.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "bad_spacing_ol_double", + source_file_name=f"{source_path}bad_spacing_ol_double.md", + source_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ol_double_config_1_2(): - """ - Test to make sure this rule does trigger with a document that - contains nested ordered lists with two space after the marker, - and configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ol_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#1", - "--set", - "plugins.md030.ol_multi=$#2", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:5:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ol_double_config_1_2_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ol_double.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "bad_spacing_ol_double_config_1_2", + source_file_name=f"{source_path}bad_spacing_ol_double.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#1", "plugins.md030.ol_multi=$#2"], + source_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#1", - "--set", - "plugins.md030.ol_multi=$#2", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ol_double_config_2_1(): - """ - Test to make sure this rule does trigger with a document that - contains nested ordered lists with two space after the marker, - and configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ol_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - ) - 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_md030_bad_spacing_ol_double_config_2_1_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ol_double.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "bad_spacing_ol_double_config_2_1", + source_file_name=f"{source_path}bad_spacing_ol_double.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#2", "plugins.md030.ol_multi=$#1"], + source_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space)\n +""", + fix_expected_file_contents="""1. First 1. Second - 1 Second - 2 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_good_spacing_ol_single_nested(): - """ - Test to make sure this rule does not trigger with a document that - contains nested ordered lists with one space after the marker, - single-paragraph and double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ol_single_nested.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_md030_bad_spacing_ol_single_nested(): - """ - Test to make sure this rule does trigger with a document that - contains nested ordered lists with two space after the marker, - single-paragraph and double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ol_single_nested.md" - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:5: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:3:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ol_single_nested_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ol_single_nested.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "good_spacing_ol_single_nested", + source_file_name=f"{source_path}good_spacing_ol_single_nested.md", + ), + pluginRuleTest( + "bad_spacing_ol_single_nested", + source_file_name=f"{source_path}bad_spacing_ol_single_nested.md", + source_file_contents="""1. First 1. Second 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:5: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""1. First 1. Second 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_good_spacing_ol_single_nested_double(): - """ - Test to make sure this rule does not trigger with a document that - contains nested ordered lists with one space after the marker, - single-paragraph and nested double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ol_single_nested_double.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_md030_good_spacing_ol_single_nested_double_2_1(): - """ - Test to make sure this rule does not trigger with a document that - contains nested ordered lists with one space after the marker, - single-paragraph and nested double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ol_single_nested_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:4: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)\n" - + f"{source_path}:7:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)" - ) - 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_md030_good_spacing_ol_single_nested_double_2_1_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_spacing_ol_single_nested_double.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "good_spacing_ol_single_nested_double", + source_file_name=f"{source_path}good_spacing_ol_single_nested_double.md", + ), + pluginRuleTest( + "good_spacing_ol_single_nested_double_2_1", + source_file_name=f"{source_path}good_spacing_ol_single_nested_double.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#2", "plugins.md030.ol_multi=$#1"], + source_file_contents="""1. First first paragraph 1. Second second paragraph 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:4: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +{temp_source_path}:7:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +""", + fix_expected_file_contents="""1. First first paragraph 1. Second second paragraph 1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ol_single_nested_double(): - """ - Test to make sure this rule does trigger with a document that - contains nested ordered lists with two space after the marker, - single-paragraph and nested double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ol_single_nested_double.md" - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:5: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:5:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ol_single_nested_double_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ol_single_nested_double.md" - ) as temp_source_path: - original_file_contents = """1. First +""", + ), + pluginRuleTest( + "bad_spacing_ol_single_nested_double", + source_file_name=f"{source_path}bad_spacing_ol_single_nested_double.md", + source_file_contents="""1. First 1. Second second paragraph 1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:5: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""1. First 1. Second second paragraph 1. Third -""" +""", + ), + pluginRuleTest( + "bad_spacing_ol_single_nested_double_2_1", + source_file_name=f"{source_path}bad_spacing_ol_single_nested_double.md", + use_strict_config=True, + set_args=["plugins.md030.ol_single=$#2", "plugins.md030.ol_multi=$#1"], + source_file_contents="""1. First + 1. Second + + second paragraph +1. Third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""1. First + 1. Second - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) + second paragraph +1. Third +""", + ), +] - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +fixTests, _ = build_fix_and_clash_lists(scanTests) -@pytest.mark.rules -def test_md030_bad_spacing_ol_single_nested_double_2_1(): +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md030_scan(test: pluginRuleTest) -> None: """ - Test to make sure this rule does trigger with a document that - contains nested ordered lists with two space after the marker, - single-paragraph and nested double-paragraph lists. + Execute a parameterized scan test for plugin md001. """ + execute_scan_test(test, "md030") - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ol_single_nested_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "--strict-config", - "--disable-rules", - "md007", - "scan", - source_path, - ] - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ol_single_nested_double_2_1_fix(): +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md030_fix(test: pluginRuleTest) -> None: """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. + Execute a parameterized fix test for plugin md001. """ + execute_fix_test(test) - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ol_single_nested_double.md" - ) as temp_source_path: - original_file_contents = """1. First - 1. Second - - second paragraph -1. Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ol_single=$#2", - "--set", - "plugins.md030.ol_multi=$#1", - "--strict-config", - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. First - 1. Second - - second paragraph -1. Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md001_config(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_configuration_test(test, f"{source_path}good_spacing_ol_single.md") diff --git a/test/rules/test_md030_unordered.py b/test/rules/test_md030_unordered.py index bed386dba..62c74376f 100644 --- a/test/rules/test_md030_unordered.py +++ b/test/rules/test_md030_unordered.py @@ -2,8 +2,15 @@ Module to provide tests related to the MD030 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + build_fix_and_clash_lists, + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, +) import pytest @@ -11,1422 +18,492 @@ source_path = os.path.join("test", "resources", "rules", "md030") + os.sep - -@pytest.mark.rules -def test_md030_bad_configuration_ul_single(): - """ - Test to verify that a configuration error is thrown when supplying the - ul_single value with a string that is not an integer. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=not-integer", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md030.ul_single' must be of type 'int'." - ) - - # 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_md030_bad_configuration_ul_single_zero(): - """ - Test to verify that a configuration error is thrown when supplying the - ul_single value with an integer not greater than 0. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#0", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md030.ul_single' is not valid: Allowable values are any integer greater than 0." - ) - - # 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_md030_bad_configuration_ul_multi(): - """ - Test to verify that a configuration error is thrown when supplying the - ul_multi value with a string that is not an integer. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_multi=not-integer", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md030.ul_multi' must be of type 'int'." - ) - - # 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_md030_bad_configuration_ul_multi_zero(): - """ - Test to verify that a configuration error is thrown when supplying the - ul_multi value with an integer not greater than 0. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_one_list.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_multi=$#0", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md030.ul_multi' is not valid: Allowable values are any integer greater than 0." - ) - - # 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_md030_good_spacing_ul_single(): - """ - Test to make sure this rule does not trigger with a document that - contains unordered lists with a single space after the marker. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ul_single.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_md030_good_spacing_ul_single_with_config_1_2(): - """ - Test to make sure this rule does not trigger with a document that - contains unordered lists with a single space after the marker, - with configuration. ul_multi does not come into effect as all - list items have a single paragraph. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ul_single.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#1", - "--set", - "plugins.md030.ul_multi=$#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_md030_good_spacing_ul_single_with_config_2_1(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. ul_multi does not come into effect - as all list items have a single paragraph. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ul_single.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)\n" - + f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)\n" - + f"{source_path}:3:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)" - ) - 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_md030_bad_spacing_ul_single(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with two spaces after the marker. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ul_single.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:3:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ul_single_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ul_single.md" - ) as temp_source_path: - original_file_contents = """* First +__plugin_disable_md005 = "md005" +__plugin_disable_md005_md007 = "md005,md007" +__plugin_disable_md007 = "md007" +__plugin_disable_md022 = "md022" + +configTests = [ + pluginConfigErrorTest( + "ul_single_type", + use_strict_config=True, + set_args=["plugins.md030.ul_single=not-integer"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md030.ul_single' must be of type 'int'.""", + ), + pluginConfigErrorTest( + "ul_single_range", + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#0"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md030.ul_single' is not valid: Allowable values are any integer greater than 0.""", + ), + pluginConfigErrorTest( + "ul_multi_type", + use_strict_config=True, + set_args=["plugins.md030.ul_multi=not-integer"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md030.ul_multi' must be of type 'int'.""", + ), + pluginConfigErrorTest( + "ul_multi_range", + use_strict_config=True, + set_args=["plugins.md030.ul_multi=$#0"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md030.ul_multi' is not valid: Allowable values are any integer greater than 0.""", + ), +] + +scanTests = [ + pluginRuleTest( + "good_spacing_ul_single", + source_file_name=f"{source_path}good_spacing_ul_single.md", + ), + pluginRuleTest( + "good_spacing_ul_single_with_config_1_2", + source_file_name=f"{source_path}good_spacing_ul_single.md", + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#1", "plugins.md030.ul_multi=$#2"], + ), + pluginRuleTest( + "bad_spacing_ul_single_with_config_2_1", + source_file_name=f"{source_path}good_spacing_ul_single.md", + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#2", "plugins.md030.ul_multi=$#1"], + source_file_contents="""* First +* Second +* Third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +{temp_source_path}:3:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + ), + pluginRuleTest( + "bad_spacing_ul_single", + source_file_name=f"{source_path}bad_spacing_ul_single.md", + source_file_contents="""* First +* Second +* Third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ul_single_config_1_2(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with two spaces after the marker and - configuration for multi line lists. ul_multi does not come into - effect as all list items have a single paragraph. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ul_single.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#1", - "--set", - "plugins.md030.ul_multi=$#2", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:3:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ul_single_config_1_2_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ul_single.md" - ) as temp_source_path: - original_file_contents = """* First +""", + ), + pluginRuleTest( + "bad_spacing_ul_single_config_1_2", + source_file_name=f"{source_path}bad_spacing_ul_single.md", + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#1", "plugins.md030.ul_multi=$#2"], + source_file_contents="""* First * Second * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#1", - "--set", - "plugins.md030.ul_multi=$#2", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ul_single_config_2_1(): - """ - Test to make sure this rule does not trigger with a document that contains - unordered lists with two spaces after the marker, and configuration to make - it okay. ul_multi does not come into effect as all list items have a single - paragraph. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ul_single.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "--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_md030_good_spacing_ul_double(): - """ - Test to make sure this rule does not trigger with a document that - contains single-paragraph unordered lists with one space after the marker. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ul_double.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_md030_good_spacing_ul_double_config_1_2(): - """ - Test to make sure this rule does trigger with a document that - contains single-paragraph unordered lists with one space after the marker, - and configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ul_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#1", - "--set", - "plugins.md030.ul_multi=$#2", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)" - ) - 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_md030_good_spacing_ul_double_config_1_2_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_spacing_ul_double.md" - ) as temp_source_path: - original_file_contents = """* First +""", + ), + pluginRuleTest( + "good_spacing_ul_single_config_2_1", + source_file_name=f"{source_path}bad_spacing_ul_single.md", + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#2", "plugins.md030.ul_multi=$#1"], + ), + pluginRuleTest( + "good_spacing_ul_double", + source_file_name=f"{source_path}good_spacing_ul_double.md", + ), + pluginRuleTest( + "good_spacing_ul_double_config_1_2", + source_file_name=f"{source_path}good_spacing_ul_double.md", + disable_rules=__plugin_disable_md005, + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#1", "plugins.md030.ul_multi=$#2"], + source_file_contents="""* First * Second - 1 Second - 2 * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#1", - "--set", - "plugins.md030.ul_multi=$#2", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second - 1 Second - 2 * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_good_spacing_ul_double_config_2_1(): - """ - Test to make sure this rule does trigger with a document that - contains single-paragraph unordered lists with one space after the marker, - and configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ul_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)\n" - + f"{source_path}:5:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)" - ) - 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_md030_good_spacing_ul_double_config_2_1_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_spacing_ul_double.md" - ) as temp_source_path: - original_file_contents = """* First +""", + ), + pluginRuleTest( + "good_spacing_ul_double_config_2_1", + disable_rules=__plugin_disable_md005, + source_file_name=f"{source_path}good_spacing_ul_double.md", + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#2", "plugins.md030.ul_multi=$#1"], + source_file_contents="""* First * Second - 1 Second - 2 * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second - 1 Second - 2 * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ul_double(): - """ - Test to make sure this rule does trigger with a document that - contains single-paragraph unordered lists with two space after the marker. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ul_double.md" - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:5:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ul_double_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ul_double.md" - ) as temp_source_path: - original_file_contents = """* First +""", + ), + pluginRuleTest( + "bad_spacing_ul_double", + source_file_name=f"{source_path}bad_spacing_ul_double.md", + source_file_contents="""* First * Second - 1 Second - 2 * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second - 1 Second - 2 * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ul_double_config_1_2(): - """ - Test to make sure this rule does trigger with a document that - contains single-paragraph unordered lists with two space after the marker, - and configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ul_double.md" - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "--set", - "plugins.md030.ul_single=$#1", - "--set", - "plugins.md030.ul_multi=$#2", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:5:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ul_double_config_1_2_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ul_double.md" - ) as temp_source_path: - original_file_contents = """* First +""", + ), + pluginRuleTest( + "bad_spacing_ul_double_config_1_2", + source_file_name=f"{source_path}bad_spacing_ul_double.md", + disable_rules=__plugin_disable_md005_md007, + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#1", "plugins.md030.ul_multi=$#2"], + source_file_contents="""* First * Second - 1 Second - 2 * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007", - "--set", - "plugins.md030.ul_single=$#1", - "--set", - "plugins.md030.ul_multi=$#2", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second - 1 Second - 2 * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ul_double_config_2_1(): - """ - Test to make sure this rule does trigger with a document that - contains single-paragraph unordered lists with two space after the marker, - and configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ul_double.md" - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - ) - 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_md030_bad_spacing_ul_double_config_2_1_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ul_double.md" - ) as temp_source_path: - original_file_contents = """* First +""", + ), + pluginRuleTest( + "bad_spacing_ul_double_config_2_1", + source_file_name=f"{source_path}bad_spacing_ul_double.md", + disable_rules=__plugin_disable_md005, + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#2", "plugins.md030.ul_multi=$#1"], + source_file_contents="""* First * Second - 1 Second - 2 * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007", - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second - 1 Second - 2 * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_good_spacing_ul_single_nested(): - """ - Test to make sure this rule does not trigger with a document that - contains nested unordered lists with one space after the marker, - single-paragraph and double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ul_single_nested.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_md030_bad_spacing_ul_single_nested(): - """ - Test to make sure this rule does trigger with a document that - contains nested unordered lists with two space after the marker, - single-paragraph and double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ul_single_nested.md" - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:4: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:3:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ul_single_nested_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ul_single_nested.md" - ) as temp_source_path: - original_file_contents = """* First +""", + ), + pluginRuleTest( + "good_spacing_ul_single_nested", + source_file_name=f"{source_path}good_spacing_ul_single_nested.md", + ), + pluginRuleTest( + "bad_spacing_ul_single_nested", + source_file_name=f"{source_path}bad_spacing_ul_single_nested.md", + disable_rules=__plugin_disable_md007, + source_file_contents="""* First * Second * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:4: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_good_spacing_ul_single_nested_double(): - """ - Test to make sure this rule does not trigger with a document that - contains nested unordered lists with one space after the marker, - single-paragraph and nested double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ul_single_nested_double.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_md030_good_spacing_ul_single_nested_double_2_1(): - """ - Test to make sure this rule does not trigger with a document that - contains nested unordered lists with one space after the marker, - single-paragraph and nested double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "good_spacing_ul_single_nested_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:3: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)\n" - + f"{source_path}:7:1: " - + "MD030: Spaces after list markers " - + "[Expected: 2; Actual: 1] (list-marker-space)" - ) - 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_md030_good_spacing_ul_single_nested_double_2_1_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "good_spacing_ul_single_nested_double.md" - ) as temp_source_path: - original_file_contents = """* First +""", + ), + pluginRuleTest( + "good_spacing_ul_single_nested_double", + source_file_name=f"{source_path}good_spacing_ul_single_nested_double.md", + ), + pluginRuleTest( + "good_spacing_ul_single_nested_double_2_1", + source_file_name=f"{source_path}good_spacing_ul_single_nested_double.md", + disable_rules=__plugin_disable_md005, + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#2", "plugins.md030.ul_multi=$#1"], + source_file_contents="""* First first paragraph * Second second paragraph * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "--strict-config", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:3: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +{temp_source_path}:7:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +""", + fix_expected_file_contents="""* First first paragraph * Second second paragraph * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ul_single_nested_double(): - """ - Test to make sure this rule does trigger with a document that - contains nested unordered lists with two space after the marker, - single-paragraph and nested double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ul_single_nested_double.md" - ) - supplied_arguments = [ - "--disable-rules", - "md007", - "scan", - source_path, - ] +""", + ), + pluginRuleTest( + "good_spacing_ul_single_nested_double_2_1_xx", + disable_rules=__plugin_disable_md005, + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#2", "plugins.md030.ul_multi=$#1"], + source_file_contents="""* First + first paragraph - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:2:4: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)\n" - + f"{source_path}:5:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - expected_error = "" + * Second - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) + second paragraph +* Third - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) +another paragraph +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:3: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +{temp_source_path}:7:1: MD030: Spaces after list markers [Expected: 2; Actual: 1] (list-marker-space) +""", + fix_expected_file_contents="""* First + first paragraph + * Second -@pytest.mark.rules -def test_md030_bad_spacing_ul_single_nested_double_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ + second paragraph +* Third - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ul_single_nested_double.md" - ) as temp_source_path: - original_file_contents = """* First +another paragraph +""", + ), + pluginRuleTest( + "bad_spacing_ul_single_nested_double", + source_file_name=f"{source_path}bad_spacing_ul_single_nested_double.md", + disable_rules=__plugin_disable_md007, + source_file_contents="""* First * Second second paragraph * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:4: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second second paragraph * Third -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md030_bad_spacing_ul_single_nested_double_2_1(): - """ - Test to make sure this rule does trigger with a document that - contains nested unordered lists with two space after the marker, - single-paragraph and nested double-paragraph lists. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md030", "bad_spacing_ul_single_nested_double.md" - ) - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "--strict-config", - "--disable-rules", - "md007", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD030: Spaces after list markers " - + "[Expected: 1; Actual: 2] (list-marker-space)" - ) - 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_md030_bad_spacing_ul_single_nested_double_2_1_fix(): - """ - Test to make sure this rule does trigger with a document that - contains unordered lists with a single space after the marker, - and configuration that applies. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_spacing_ul_single_nested_double.md" - ) as temp_source_path: - original_file_contents = """* First +""", + ), + pluginRuleTest( + "bad_spacing_ul_single_nested_double_2_1", + source_file_name=f"{source_path}bad_spacing_ul_single_nested_double.md", + use_strict_config=True, + set_args=["plugins.md030.ul_single=$#2", "plugins.md030.ul_multi=$#1"], + disable_rules=__plugin_disable_md005_md007, + source_file_contents="""* First * Second second paragraph * Third -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md030.ul_single=$#2", - "--set", - "plugins.md030.ul_multi=$#1", - "--strict-config", - "--disable-rules", - "md007", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """* First +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First * Second second paragraph * Third -""" +""", + ), + pluginRuleTest( + "mix_md030_md005", + source_file_contents="""+ Heading 1 + + Heading 2 + + Heading 3 + + Heading 4 +""", + disable_rules=__plugin_disable_md007, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:2: MD005: Inconsistent indentation for list items at the same level [Expected: 1; Actual: 1] (list-indent) +{temp_source_path}:2:2: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:5: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:4:6: MD005: Inconsistent indentation for list items at the same level [Expected: 5; Actual: 5] (list-indent) +{temp_source_path}:4:6: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""+ Heading 1 ++ Heading 2 + + Heading 3 + + Heading 4 +""", + ), + pluginRuleTest( + "mix_md030_md007", + source_file_contents=""" * First + first paragraph + + * Second - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) + second paragraph + * Third +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:1:2: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:4:5: MD007: Unordered list indentation [Expected: 2, Actual=4] (ul-indent) +{temp_source_path}:4:5: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:7:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:7:2: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* First + first paragraph - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) + * Second + + second paragraph +* Third +""", + ), + pluginRuleTest( + "mix_md030_md010", + source_file_contents="""* # list item\t1 +* ## list\titem 2 + + paragraph +* ## list\titem 3 +""", + disable_rules=__plugin_disable_md022, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:1:15: MD010: Hard tabs [Column: 15] (no-hard-tabs) +{temp_source_path}:2:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +{temp_source_path}:5:1: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:11: MD010: Hard tabs [Column: 11] (no-hard-tabs) +""", + fix_expected_file_contents="""* # list item 1 +* ## list item 2 + + paragraph +* ## list item 3 +""", + ), + pluginRuleTest( + "mix_md030_md023", + source_file_contents=""" * # Heading 1 + + * ## Heading 2 + + * ### Heading 3 +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD007: Unordered list indentation [Expected: 0, Actual=1] (ul-indent) +{temp_source_path}:1:2: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:3:5: MD007: Unordered list indentation [Expected: 2, Actual=4] (ul-indent) +{temp_source_path}:3:5: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:5:8: MD007: Unordered list indentation [Expected: 4, Actual=7] (ul-indent) +{temp_source_path}:5:8: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""* # Heading 1 + + * ## Heading 2 + + * ### Heading 3 +""", + ), + pluginRuleTest( + "mix_md030_md027", + source_file_contents="""> * Heading 1 +> * Heading 2 +""", + disable_rules=__plugin_disable_md007, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:1:4: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +{temp_source_path}:2:3: MD027: Multiple spaces after blockquote symbol (no-multiple-space-blockquote) +{temp_source_path}:2:4: MD030: Spaces after list markers [Expected: 1; Actual: 2] (list-marker-space) +""", + fix_expected_file_contents="""> * Heading 1 +> * Heading 2 +""", + ), +] + +fixTests, _ = build_fix_and_clash_lists(scanTests) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md030_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md030") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md030_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) + + +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md030_config(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_configuration_test(test, f"{source_path}good_spacing_ul_single.md") diff --git a/test/rules/test_md035.py b/test/rules/test_md035.py index 281195e92..25245c441 100644 --- a/test/rules/test_md035.py +++ b/test/rules/test_md035.py @@ -2,1021 +2,270 @@ Module to provide tests related to the MD035 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, +) import pytest source_path = os.path.join("test", "resources", "rules", "md035") + os.sep - -@pytest.mark.rules -def test_md035_bad_configuration_style(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with an integer that is not a string. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_dash.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=$#1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md035.style' must be of type 'str'." - ) - - # 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_md035_bad_configuration_style_leading_spaces(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with string specifying thematic break with leading spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_dash.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style= ---", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md035.style' is not valid: Allowable values cannot including leading or trailing spaces." - ) - - # 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_md035_bad_configuration_style_empty(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with string specifying thematic break that is empty - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_dash.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md035.style' is not valid: Allowable values are: consistent, '---', '***', `___`, or any other horizontal rule text." - ) - - # 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_md035_bad_configuration_style_trailing_spaces(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with string specifying thematic break with trailing spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_dash.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=--- ", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md035.style' is not valid: Allowable values cannot including leading or trailing spaces." - ) - - # 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_md035_bad_configuration_style_bad_character(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with string specifying thematic break with a bad character. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_dash.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=-=-=-", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md035.style' is not valid: Allowable values are: consistent, '---', '***', `___`, or any other horizontal rule text." - ) - - # 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_md035_bad_configuration_style_mixed_characters(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with string specifying valid thematic break characters that - are not the same as each other. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_dash.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=*-*-*-*", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md035.style' is not valid: Allowable values are: consistent, '---', '***', `___`, or any other horizontal rule text." - ) - - # 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_md035_good_configuration_style_consistent(): - """ - Test to make sure this rule does not trigger with a document that - contains thematic breaks that are consistent dashes with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_dash.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=consistent", - "--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_md035_good_consistent_dash(): - """ - Test to make sure this rule does not trigger with a document that - contains thematic breaks that are consistent dashes with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_dash.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_md035_bad_consistent_dash(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not consistent dashes with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "bad_consistent_dash.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:1: " - + "MD035: Horizontal rule style " - + "[Expected: ---, Actual: - - -] (hr-style)" - ) - 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_md035_bad_consistent_dash_fix(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not consistent dashes with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_consistent_dash.md") as temp_source_path: - original_file_contents = """--- +configTests = [ + pluginConfigErrorTest( + "invalid_style_type", + use_strict_config=True, + set_args=["plugins.md035.style=$#1"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md035.style' must be of type 'str'.""", + ), + pluginConfigErrorTest( + "invalid_style_both_spaces", + use_strict_config=True, + set_args=["plugins.md035.style= ---"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md035.style' is not valid: Allowable values cannot including leading or trailing spaces.""", + ), + pluginConfigErrorTest( + "invalid_style_empty", + use_strict_config=True, + set_args=["plugins.md035.style="], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md035.style' is not valid: Allowable values are: consistent, '---', '***', `___`, or any other horizontal rule text.""", + ), + pluginConfigErrorTest( + "invalid_style_trailing_spaces", + use_strict_config=True, + set_args=["plugins.md035.style=--- "], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md035.style' is not valid: Allowable values cannot including leading or trailing spaces.""", + ), + pluginConfigErrorTest( + "invalid_style_bad_character", + use_strict_config=True, + set_args=["plugins.md035.style=-=-=-"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md035.style' is not valid: Allowable values are: consistent, '---', '***', `___`, or any other horizontal rule text.""", + ), + pluginConfigErrorTest( + "invalid_style_mixed_valid_character", + use_strict_config=True, + set_args=["plugins.md035.style=*-*-*-*"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md035.style' is not valid: Allowable values are: consistent, '---', '***', `___`, or any other horizontal rule text.""", + ), + pluginConfigErrorTest( + "invalid_style_mixed_valid_character", + use_strict_config=True, + set_args=["plugins.md035.style=*-*-*-*"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md035.style' is not valid: Allowable values are: consistent, '---', '***', `___`, or any other horizontal rule text.""", + ), +] + + +scanTests = [ + pluginRuleTest( + "good_consistent_dash", + source_file_name=f"{source_path}good_consistent_dash.md", + ), + pluginRuleTest( + "good_consistent_dash_with_configuration", + source_file_name=f"{source_path}good_consistent_dash.md", + use_strict_config=True, + set_args=["plugins.md035.style=consistent"], + ), + pluginRuleTest( + "bad_consistent_dash", + source_file_name=f"{source_path}bad_consistent_dash.md", + source_file_contents="""--- this is one section - - - -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """--- +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:1: MD035: Horizontal rule style [Expected: ---, Actual: - - -] (hr-style) +""", + fix_expected_file_contents="""--- this is one section --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md035_bad_consistent_dash_with_leading_spaces(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not consistent dashes with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md035", - "bad_consistent_dash_with_leading_spaces.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:2: " - + "MD035: Horizontal rule style " - + "[Expected: ---, Actual: - - -] (hr-style)" - ) - 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_md035_bad_consistent_dash_with_leading_spaces_fix(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not consistent dashes with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_consistent_dash_with_leading_spaces.md" - ) as temp_source_path: - original_file_contents = """--- +""", + ), + pluginRuleTest( + "bad_consistent_dash_with_leading_spaces", + source_file_name=f"{source_path}bad_consistent_dash_with_leading_spaces.md", + source_file_contents="""--- this is one section - - - -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """--- +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:2: MD035: Horizontal rule style [Expected: ---, Actual: - - -] (hr-style) +""", + fix_expected_file_contents="""--- this is one section --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md035_good_dash_marker(): - """ - Test to make sure this rule does not trigger with a document that - contains thematic breaks that are three dashes with configuration of three dashes. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_dash.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=---", - "--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_md035_bad_dash_marker(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not three dashes with configuration of three dashes. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "bad_consistent_dash.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=---", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:1: " - + "MD035: Horizontal rule style " - + "[Expected: ---, Actual: - - -] (hr-style)" - ) - 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_md035_bad_dash_marker_fix(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not consistent dashes with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_consistent_dash.md") as temp_source_path: - original_file_contents = """--- +""", + ), + pluginRuleTest( + "good_dash_marker", + source_file_name=f"{source_path}good_consistent_dash.md", + set_args=["plugins.md035.style=---"], + use_strict_config=True, + ), + pluginRuleTest( + "bad_dash_marker", + source_file_name=f"{source_path}bad_consistent_dash.md", + set_args=["plugins.md035.style=---"], + use_strict_config=True, + source_file_contents="""--- this is one section - - - -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """--- +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:1: MD035: Horizontal rule style [Expected: ---, Actual: - - -] (hr-style) +""", + fix_expected_file_contents="""--- this is one section --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md035_good_consistent_asterisk(): - """ - Test to make sure this rule does not trigger with a document that - contains thematic breaks that are asterisks with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_asterisk.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_md035_bad_consistent_asterisk(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are different asterisks with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "bad_consistent_asterisk.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:1: " - + "MD035: Horizontal rule style " - + "[Expected: ***, Actual: * * *] (hr-style)" - ) - 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_md035_bad_consistent_asterisk_fix(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not consistent dashes with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_consistent_asterisk.md" - ) as temp_source_path: - original_file_contents = """*** +""", + ), + pluginRuleTest( + "good_consistent_asterisk", + source_file_name=f"{source_path}good_consistent_asterisk.md", + ), + pluginRuleTest( + "bad_consistent_asterisk", + source_file_name=f"{source_path}bad_consistent_asterisk.md", + source_file_contents="""*** this is one section * * * -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """*** +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:1: MD035: Horizontal rule style [Expected: ***, Actual: * * *] (hr-style) +""", + fix_expected_file_contents="""*** this is one section *** -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md035_good_asterisk_marker(): - """ - Test to make sure this rule does not trigger with a document that - contains thematic breaks that are three asterisk with configuration of three asterisks. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_asterisk.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=* * *", - "--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_md035_bad_asterisk_marker(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are three asterisk with configuration of different three asterisks. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "bad_consistent_asterisk.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=* * *", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD035: Horizontal rule style " - + "[Expected: * * *, Actual: ***] (hr-style)" - ) - 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_md035_bad_asterisk_marker_fix(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not consistent dashes with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_consistent_asterisk.md" - ) as temp_source_path: - original_file_contents = """*** +""", + ), + pluginRuleTest( + "good_asterisk_marker", + source_file_name=f"{source_path}good_consistent_asterisk.md", + use_strict_config=True, + set_args=["plugins.md035.style=* * *"], + ), + pluginRuleTest( + "bad_asterisk_marker", + source_file_name=f"{source_path}bad_consistent_asterisk.md", + source_file_contents="""*** this is one section * * * -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """*** +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:1: MD035: Horizontal rule style [Expected: ***, Actual: * * *] (hr-style) +""", + fix_expected_file_contents="""*** this is one section *** -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md035_good_consistent_underscore(): - """ - Test to make sure this rule does not trigger with a document that - contains thematic breaks that are three underscores with consistent. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_underscore.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 - ) +""", + ), + pluginRuleTest( + "good_consistent_underscore", + source_file_name=f"{source_path}good_consistent_underscore.md", + ), + pluginRuleTest( + "bad_consistent_underscore", + source_file_name=f"{source_path}bad_consistent_underscore.md", + source_file_contents="""___ +this is one section -@pytest.mark.rules -def test_md035_bad_consistent_underscore(): - """ - Test to make sure this rule does not trigger with a document that - contains thematic breaks that are underscores with consistent and different underscores. - """ +______ +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:1: MD035: Horizontal rule style [Expected: ___, Actual: ______] (hr-style) +""", + fix_expected_file_contents="""___ - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "bad_consistent_underscore.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:5:1: " - + "MD035: Horizontal rule style " - + "[Expected: ___, Actual: ______] (hr-style)" - ) - 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_md035_bad_consistent_underscore_fix(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not consistent dashes with consistent. - """ +this is one section - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_consistent_underscore.md" - ) as temp_source_path: - original_file_contents = """___ +___ +""", + ), + pluginRuleTest( + "good_underscore_marker", + source_file_name=f"{source_path}good_consistent_underscore.md", + use_strict_config=True, + set_args=["plugins.md035.style=______"], + ), + pluginRuleTest( + "bad_underscore_marker", + source_file_name=f"{source_path}bad_consistent_underscore.md", + source_file_contents="""___ this is one section ______ -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """___ +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:1: MD035: Horizontal rule style [Expected: ___, Actual: ______] (hr-style) +""", + fix_expected_file_contents="""___ this is one section ___ -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - -@pytest.mark.rules -def test_md035_good_underscore_marker(): +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md035_scan(test: pluginRuleTest) -> None: """ - Test to make sure this rule does not trigger with a document that - contains thematic breaks that are underscores with configuration to match. + Execute a parameterized scan test for plugin md001. """ + execute_scan_test(test, "md035") - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "good_consistent_underscore.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=______", - "--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_md035_bad_underscore_marker(): - """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are underscores with configuration that does not match. - """ - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md035", "bad_consistent_underscore.md" - ) - supplied_arguments = [ - "--set", - "plugins.md035.style=______", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD035: Horizontal rule style " - + "[Expected: ______, Actual: ___] (hr-style)" - ) - 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_md035_bad_underscore_marker_fix(): +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md035_fix(test: pluginRuleTest) -> None: """ - Test to make sure this rule does trigger with a document that - contains thematic breaks that are not consistent dashes with consistent. + Execute a parameterized fix test for plugin md001. """ + execute_fix_test(test) - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_consistent_underscore.md" - ) as temp_source_path: - original_file_contents = """___ - -this is one section - -______ -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = """___ - -this is one section - -___ -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md035_config(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_configuration_test(test, f"{source_path}good_consistent_dash.md") diff --git a/test/rules/test_md037.py b/test/rules/test_md037.py index 8dee96bc4..43d6605a7 100644 --- a/test/rules/test_md037.py +++ b/test/rules/test_md037.py @@ -2,353 +2,104 @@ Module to provide tests related to the MD037 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import ( - assert_file_is_as_expected, - copy_to_temp_file, - create_temporary_configuration_file, +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, ) import pytest source_path = os.path.join("test", "resources", "rules", "md037") + os.sep - -@pytest.mark.rules -def test_md037_good_valid_emphasis(): - """ - Test to make sure this rule does not trigger with a document that - contains one or more valid emphasis sequences. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "good_valid_emphasis.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_md037_bad_surrounding_emphasis(): - """ - Test to make sure this rule does trigger with a document that - contains one or two valid emphasis characters surrounded by spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "bad_surrounding_emphasis.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:3:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:5:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)" - ) - 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_md037_bad_surrounding_emphasis_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_surrounding_emphasis.md" - ) as temp_source_path: - original_file_contents = """this text * is * in italics +scanTests = [ + pluginRuleTest( + "good_valid_emphasis", + source_file_name=f"{source_path}good_valid_emphasis.md", + ), + pluginRuleTest( + "bad_surrounding_emphasis", + source_file_name=f"{source_path}bad_surrounding_emphasis.md", + source_file_contents="""this text * is * in italics this text _ is _ in italics this text ** is ** in bold this text __ is __ in bold -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this text *is* in italics +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:3:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:5:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""this text *is* in italics this text _is_ in italics this text **is** in bold this text __is__ in bold -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md037_bad_leading_emphasis(): - """ - Test to make sure this rule does trigger with a document that - contains one or two valid emphasis characters with leading spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "bad_leading_emphasis.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:3:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:5:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)" - ) - 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_md037_bad_leading_emphasis_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_leading_emphasis.md") as temp_source_path: - original_file_contents = """this text * is* in italics +""", + ), + pluginRuleTest( + "bad_leading_emphasis", + source_file_name=f"{source_path}bad_leading_emphasis.md", + source_file_contents="""this text * is* in italics this text _ is_ in italics this text ** is** in bold this text __ is__ in bold -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this text *is* in italics +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:3:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:5:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""this text *is* in italics this text _is_ in italics this text **is** in bold this text __is__ in bold -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md037_bad_trailing_emphasis(): - """ - Test to make sure this rule does trigger with a document that - contains one or two valid emphasis characters followed by spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "bad_trailing_emphasis.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:3:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:5:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)" - ) - 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_md037_bad_trailing_emphasis_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_trailing_emphasis.md" - ) as temp_source_path: - original_file_contents = """this text *is * in italics +""", + ), + pluginRuleTest( + "bad_trailing_emphasis", + source_file_name=f"{source_path}bad_trailing_emphasis.md", + source_file_contents="""this text *is * in italics this text _is _ in italics this text **is ** in bold this text __is __ in bold -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this text *is* in italics +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:3:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:5:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""this text *is* in italics this text _is_ in italics this text **is** in bold this text __is__ in bold -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md037_bad_surrounding_emphasis_multiline(): - """ - Test to make sure this rule does trigger with a document that - contains one or two valid emphasis characters surrounded by spaces, - and the emphasis spans lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "bad_surrounding_emphasis_multiline.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:4:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:10:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)" - ) - 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_md037_bad_surrounding_emphasis_multiline_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_surrounding_emphasis_multiline.md" - ) as temp_source_path: - original_file_contents = """this text * is +""", + ), + pluginRuleTest( + "bad_surrounding_emphasis_multiline", + source_file_name=f"{source_path}bad_surrounding_emphasis_multiline.md", + source_file_contents="""this text * is not * in italics this text _ is @@ -359,20 +110,14 @@ def test_md037_bad_surrounding_emphasis_multiline_fix(): this text __ is not __ in bold -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this text *is +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:4:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:10:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""this text *is not* in italics this text _is @@ -383,67 +128,12 @@ def test_md037_bad_surrounding_emphasis_multiline_fix(): this text __is not__ in bold -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md037_bad_surrounding_empahsis_setext(): - """ - Test to make sure this rule does trigger with a document that - contains one or two valid emphasis characters surrounded by spaces, - within an SetExt heading. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "bad_surrounding_empahsis_setext.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:4:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:10:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)" - ) - 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_md037_bad_surrounding_empahsis_setext_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_surrounding_empahsis_setext.md" - ) as temp_source_path: - original_file_contents = """this text * is * in italics +""", + ), + pluginRuleTest( + "bad_surrounding_empahsis_setext", + source_file_name=f"{source_path}bad_surrounding_empahsis_setext.md", + source_file_contents="""this text * is * in italics === this text _ is _ in italics @@ -454,20 +144,14 @@ def test_md037_bad_surrounding_empahsis_setext_fix(): this text __ is __ in bold --- -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this text *is* in italics +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:4:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:7:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:10:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""this text *is* in italics === this text _is_ in italics @@ -478,387 +162,111 @@ def test_md037_bad_surrounding_empahsis_setext_fix(): this text __is__ in bold --- -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md037_bad_surrounding_empahsis_atx(): - """ - Test to make sure this rule does trigger with a document that - contains one or two valid emphasis characters surrounded by spaces, - within an Atx Heading element. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "bad_surrounding_empahsis_atx.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:13: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:3:14: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:5:14: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:7:14: MD037: Spaces inside emphasis markers (no-space-in-emphasis)" - ) - 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_md037_bad_surrounding_empahsis_atx_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_surrounding_empahsis_atx.md" - ) as temp_source_path: - original_file_contents = """# this text * is * in italics +""", + ), + pluginRuleTest( + "bad_surrounding_empahsis_atx", + source_file_name=f"{source_path}bad_surrounding_empahsis_atx.md", + source_file_contents="""# this text * is * in italics ## this text _ is _ in italics ## this text ** is ** in bold ## this text __ is __ in bold -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """# this text *is* in italics +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:13: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:3:14: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:5:14: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:7:14: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""# this text *is* in italics ## this text _is_ in italics ## this text **is** in bold ## this text __is__ in bold -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md037_bad_surrounding_emphasis_containers(): - """ - Test to make sure this rule does trigger with a document that - contains one or two valid emphasis characters surrounded by spaces, - within a single line within a container element. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "bad_surrounding_emphasis_containers.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:12: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:3:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)\n" - + f"{source_path}:5:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis)" - ) - 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_md037_bad_surrounding_emphasis_containers_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_surrounding_emphasis_containers.md" - ) as temp_source_path: - original_file_contents = """1. this is * not in * italics +""", + ), + pluginRuleTest( + "bad_surrounding_emphasis_containers", + source_file_name=f"{source_path}bad_surrounding_emphasis_containers.md", + source_file_contents="""1. this is * not in * italics + this is * not in * italics > this is * not in * italics -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """1. this is *not in* italics +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:12: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:3:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +{temp_source_path}:5:11: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""1. this is *not in* italics + this is *not in* italics > this is *not in* italics -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md037_good_emphasis_with_code_span(): - """ - Test to make sure this rule does not trigger with a document that - contains one or two valid emphasis characters surrounded by spaces, - within a code span. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "good_emphasis_with_code_span.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_md037_good_no_emphasis_but_stars(): - """ - Test to make sure this rule does not trigger with a document that - contains one or two valid emphasis characters as part of other parts - of a paragraph. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md037", "good_no_emphasis_but_stars.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_md037_bad_surrounding_emphasis_link_surround(): - """ - Test to make sure this rule does trigger with a document that - contains one or two valid emphasis characters surrounded by spaces, - within a single line within a container element. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """abc * [link](/url) * ghi -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = f"{temp_source_path}:1:5: MD037: Spaces inside emphasis markers (no-space-in-emphasis)" - 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_md037_bad_surrounding_emphasis_link_surround_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """abc * [link](/url) * ghi""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """abc *[link](/url)* ghi -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md037_bad_surrounding_emphasis_link_before_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """abc * [link](/url)* ghi -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """abc *[link](/url)* ghi -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md037_bad_surrounding_emphasis_link_after_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - original_file_contents = """abc *[link](/url) * ghi -""" - with create_temporary_configuration_file( - original_file_contents, file_name_suffix=".md" - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """abc *[link](/url)* ghi -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +""", + ), + pluginRuleTest( + "good_emphasis_with_code_span", + source_file_name=f"{source_path}good_emphasis_with_code_span.md", + ), + pluginRuleTest( + "good_no_emphasis_but_stars", + source_file_name=f"{source_path}good_no_emphasis_but_stars.md", + ), + pluginRuleTest( + "bad_surrounding_emphasis_link_surround", + source_file_contents="""abc * [link](/url) * ghi +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:5: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""abc *[link](/url)* ghi +""", + ), + pluginRuleTest( + "bad_surrounding_emphasis_link_before_fix", + source_file_contents="""abc * [link](/url)* ghi +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:5: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""abc *[link](/url)* ghi +""", + ), + pluginRuleTest( + "bad_surrounding_emphasis_link_after_fix", + source_file_contents="""abc *[link](/url) * ghi +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:5: MD037: Spaces inside emphasis markers (no-space-in-emphasis) +""", + fix_expected_file_contents="""abc *[link](/url)* ghi +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md037_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md037") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md037_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) diff --git a/test/rules/test_md038.py b/test/rules/test_md038.py index b487d2056..021e55712 100644 --- a/test/rules/test_md038.py +++ b/test/rules/test_md038.py @@ -2,433 +2,101 @@ Module to provide tests related to the MD038 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, +) import pytest - -@pytest.mark.rules -def test_md038_good_code_span(): - """ - Test to make sure this rule does not trigger with a document that - contains a code span element that does not start or end with spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md038", "good_code_span.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_md038_bad_code_span_trailing(): - """ - Test to make sure this rule does trigger with a document that - contains a code span element that end with spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md038", "bad_code_span_trailing.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:9: " - + "MD038: Spaces inside code span elements (no-space-in-code)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - - source_path = os.path.join("test", "resources", "rules", "md038") + os.sep +scanTests = [ + pluginRuleTest( + "good_code_span", + source_file_name=f"{source_path}good_code_span.md", + ), + pluginRuleTest( + "bad_code_span_trailing", + source_file_name=f"{source_path}bad_code_span_trailing.md", + source_file_contents="""this is `bad code span ` text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:9: MD038: Spaces inside code span elements (no-space-in-code) +""", + fix_expected_file_contents="""this is `bad code span` text +""", + ), + pluginRuleTest( + "bad_code_span_leading", + source_file_name=f"{source_path}bad_code_span_leading.md", + source_file_contents="""this is ` bad code span` text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:9: MD038: Spaces inside code span elements (no-space-in-code) +""", + fix_expected_file_contents="""this is `bad code span` text +""", + ), + pluginRuleTest( + "good_code_span_both", + source_file_name=f"{source_path}good_code_span_both.md", + ), + pluginRuleTest( + "bad_code_span_both_extra", + source_file_name=f"{source_path}bad_code_span_both_extra.md", + source_file_contents="""this is ` bad code span ` text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:9: MD038: Spaces inside code span elements (no-space-in-code) +""", + fix_expected_file_contents="""this is ` bad code span ` text +""", + ), + pluginRuleTest( + "good_code_span_embedded_leading_backtick", + source_file_name=f"{source_path}good_code_span_embedded_leading_backtick.md", + ), + pluginRuleTest( + "good_code_span_embedded_trailing_backtick", + source_file_name=f"{source_path}good_code_span_embedded_trailing_backtick.md", + ), + pluginRuleTest( + "bad_code_span_empty", + source_file_name=f"{source_path}bad_code_span_empty.md", + source_file_contents="""this is an almost empty ` ` codepsan -@pytest.mark.rules -def test_md038_bad_code_span_trailing_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_code_span_trailing.md" - ) as temp_source_path: - original_file_contents = """this is `bad code span ` text -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is `bad code span` text -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md038_bad_code_span_leading(): - """ - Test to make sure this rule does trigger with a document that - contains a code span element that starts with spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md038", "bad_code_span_leading.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:9: " - + "MD038: Spaces inside code span elements (no-space-in-code)" - ) - 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_md038_bad_code_span_leading_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_code_span_leading.md" - ) as temp_source_path: - original_file_contents = """this is ` bad code span` text -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is `bad code span` text -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md038_good_code_span_both(): - """ - Test to make sure this rule does not trigger with a document that - contains a code span element that starts and ends with a single space. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md038", "good_code_span_both.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_md038_bad_code_span_both_extra(): - """ - Test to make sure this rule does trigger with a document that - contains a code span element that starts and ends with multiple spaces. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md038", "bad_code_span_both_extra.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:9: " - + "MD038: Spaces inside code span elements (no-space-in-code)" - ) - 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_md038_bad_code_span_both_extra_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_code_span_both_extra.md" - ) as temp_source_path: - original_file_contents = """this is ` bad code span ` text -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is ` bad code span ` text -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md038_good_code_span_embedded_leading_backtick(): - """ - Test to make sure this rule does not trigger with a document that - contains a code span element that starts with a single space - followed by a backtick. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md038", - "good_code_span_embedded_leading_backtick.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_md038_good_code_span_embedded_trailing_backtick(): - """ - Test to make sure this rule does not trigger with a document that - contains a code span element that ends with a single backtick - followed by a space. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", - "resources", - "rules", - "md038", - "good_code_span_embedded_trailing_backtick.md", - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 0 - expected_output = "" - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) +this is an only spaces ` ` codepsan +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:25: MD038: Spaces inside code span elements (no-space-in-code) +{temp_source_path}:3:24: MD038: Spaces inside code span elements (no-space-in-code) +""", + fix_expected_file_contents="""this is an almost empty `` codepsan - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) +this is an only spaces `` codepsan +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) -@pytest.mark.rules -def test_md038_bad_code_span_empty(): +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md038_scan(test: pluginRuleTest) -> None: """ - Test to make sure we get the expected behavior after scanning a good file from the - test/resources/rules/md004 directory that has consistent asterisk usage on a single - level list. + Execute a parameterized scan test for plugin md001. """ + execute_scan_test(test, "md038") - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md038", "bad_code_span_empty.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:25: " - + "MD038: Spaces inside code span elements (no-space-in-code)\n" - + f"{source_path}:3:24: " - + "MD038: Spaces inside code span elements (no-space-in-code)" - ) - 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_md038_bad_code_span_empty_fix(): +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md038_fix(test: pluginRuleTest) -> None: """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. + Execute a parameterized fix test for plugin md001. """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file(source_path + "bad_code_span_empty.md") as temp_source_path: - original_file_contents = """this is an almost empty ` ` codepsan - -this is an only spaces ` ` codepsan -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 0 - expected_output = "" - expected_error = "" - - expected_file_contents = """this is an almost empty ` ` codepsan - -this is an only spaces ` ` codepsan -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) + execute_fix_test(test) diff --git a/test/rules/test_md039.py b/test/rules/test_md039.py index 52788398e..dc4dcf219 100644 --- a/test/rules/test_md039.py +++ b/test/rules/test_md039.py @@ -2,1185 +2,273 @@ Module to provide tests related to the MD039 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, +) import pytest source_path = os.path.join("test", "resources", "rules", "md039") + os.sep -@pytest.mark.rules -def test_md039_good_inline_link(): - """ - Test to make sure this rule does not trigger with a document that - contains an inline link with no space on either side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "good_inline_link.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_md039_bad_inline_link_trailing_space(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_inline_link_trailing_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_inline_link_trailing_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_inline_link_trailing_space.md" - ) as temp_source_path: - original_file_contents = """this is not +scanTests = [ + pluginRuleTest( + "good_inline_link", + source_file_name=f"{source_path}good_inline_link.md", + ), + pluginRuleTest( + "bad_inline_link_trailing_space", + source_file_name=f"{source_path}bad_inline_link_trailing_space.md", + source_file_contents="""this is not [a proper ](https://www.example.com) link -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not [a proper](https://www.example.com) link -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_bad_inline_link_leading_space(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the left side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_inline_link_leading_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_inline_link_leading_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_inline_link_leading_space.md" - ) as temp_source_path: - original_file_contents = """this is not +""", + ), + pluginRuleTest( + "bad_inline_link_leading_space", + source_file_name=f"{source_path}bad_inline_link_leading_space.md", + source_file_contents="""this is not [ a proper](https://www.example.com) link -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not [a proper](https://www.example.com) link -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_bad_inline_link_both_space(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on both sides of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_inline_link_both_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_inline_link_both_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_inline_link_both_space.md" - ) as temp_source_path: - original_file_contents = """this is not +""", + ), + pluginRuleTest( + "bad_inline_link_both_space", + source_file_name=f"{source_path}bad_inline_link_both_space.md", + source_file_contents="""this is not [ a proper ](https://www.example.com) link -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not [a proper](https://www.example.com) link -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_good_full_link(): - """ - Test to make sure this rule does not trigger with a document that - contains a full link with no space on either side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "good_full_link.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_md039_bad_full_link_both_space(): - """ - Test to make sure this rule does trigger with a document that - contains a full link with space on both sides of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_full_link_both_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_full_link_both_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_full_link_both_space.md" - ) as temp_source_path: - original_file_contents = """this is +""", + ), + pluginRuleTest( + "good_full_link", + source_file_name=f"{source_path}good_full_link.md", + ), + pluginRuleTest( + "bad_full_link_both_space", + source_file_name=f"{source_path}bad_full_link_both_space.md", + source_file_contents="""this is [ a proper ][bar] link [bar]: /url -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is [a proper][bar] link [bar]: /url -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_good_collapsed_link(): - """ - Test to make sure this rule does not trigger with a document that - contains a collapsed link with no space on either side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "good_collapsed_link.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_md039_bad_collapsed_link_both_space(): - """ - Test to make sure this rule does not trigger with a document that - contains a collapsed link with space on both sides of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_collapsed_link_both_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_collapsed_link_both_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_collapsed_link_both_space.md" - ) as temp_source_path: - original_file_contents = """this is not +""", + ), + pluginRuleTest( + "good_collapsed_link", + source_file_name=f"{source_path}good_collapsed_link.md", + ), + pluginRuleTest( + "bad_collapsed_link_both_space", + source_file_name=f"{source_path}bad_collapsed_link_both_space.md", + source_file_contents="""this is not [ a proper ][] link [ a proper ]: /url -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not [a proper][] link [ a proper ]: /url -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_good_shortcut_link(): - """ - Test to make sure this rule does not trigger with a document that - contains a shortcut link with no space on either side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "good_shortcut_link.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_md039_bad_shortcut_link_both_space(): - """ - Test to make sure this rule does not trigger with a document that - contains a shortcut link with spaces on both sides of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_shortcut_link_both_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_shortcut_link_both_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_shortcut_link_both_space.md" - ) as temp_source_path: - original_file_contents = """this is not +""", + ), + pluginRuleTest( + "good_shortcut_link", + source_file_name=f"{source_path}good_shortcut_link.md", + ), + pluginRuleTest( + "bad_shortcut_link_both_space", + source_file_name=f"{source_path}bad_shortcut_link_both_space.md", + source_file_contents="""this is not [ a proper ] link [ a proper ]: /url -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not [a proper] link [ a proper ]: /url -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_good_inline_image(): - """ - Test to make sure this rule does not trigger with a document that - contains an inline image with no space on either side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "good_inline_image.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_md039_bad_inline_image_trailing_space(): - """ - Test to make sure this rule does trigger with a document that - contains an inline image with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_inline_image_trailing_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_inline_image_trailing_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_inline_image_trailing_space.md" - ) as temp_source_path: - original_file_contents = """this is not +""", + ), + pluginRuleTest( + "good_inline_image", + source_file_name=f"{source_path}good_inline_image.md", + ), + pluginRuleTest( + "bad_inline_image_trailing_space", + source_file_name=f"{source_path}bad_inline_image_trailing_space.md", + source_file_contents="""this is not ![a proper ](https://www.example.com) link -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not ![a proper](https://www.example.com) link -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_bad_inline_image_leading_space(): - """ - Test to make sure this rule does trigger with a document that - contains an inline image with space on the left side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_inline_image_leading_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_inline_image_leading_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_inline_image_leading_space.md" - ) as temp_source_path: - original_file_contents = """this is not +""", + ), + pluginRuleTest( + "bad_inline_image_leading_space", + source_file_name=f"{source_path}bad_inline_image_leading_space.md", + source_file_contents="""this is not ![ a proper](https://www.example.com) link -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not ![a proper](https://www.example.com) link -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_bad_inline_image_both_space(): - """ - Test to make sure this rule does trigger with a document that - contains an inline image with space on both sides of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_inline_image_both_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_inline_image_both_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_inline_image_both_space.md" - ) as temp_source_path: - original_file_contents = """this is not +""", + ), + pluginRuleTest( + "bad_inline_image_both_space", + source_file_name=f"{source_path}bad_inline_image_both_space.md", + source_file_contents="""this is not ![ a proper ](https://www.example.com) link -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not ![a proper](https://www.example.com) link -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_good_full_image(): - """ - Test to make sure this rule does not trigger with a document that - contains a full image with no space on either side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "good_full_image.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_md039_bad_full_image_both_space(): - """ - Test to make sure this rule does not trigger with a document that - contains a full image with spaces on both sides of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_full_image_both_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_full_image_both_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_full_image_both_space.md" - ) as temp_source_path: - original_file_contents = """this is +""", + ), + pluginRuleTest( + "good_full_image", + source_file_name=f"{source_path}good_full_image.md", + ), + pluginRuleTest( + "bad_full_image_both_space", + source_file_name=f"{source_path}bad_full_image_both_space.md", + source_file_contents="""this is ![ a proper ][bar] link [bar]: /url -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is ![a proper][bar] link [bar]: /url -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_good_collapsed_image(): - """ - Test to make sure this rule does not trigger with a document that - contains a collapsed image with no space on either side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "good_collapsed_image.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_md039_bad_collapsed_image_both_space(): - """ - Test to make sure this rule does trigger with a document that - contains a collapsed image with spaces on both sides of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_collapsed_image_both_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_collapsed_image_both_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_collapsed_image_both_space.md" - ) as temp_source_path: - original_file_contents = """this is not +""", + ), + pluginRuleTest( + "good_collapsed_image", + source_file_name=f"{source_path}good_collapsed_image.md", + ), + pluginRuleTest( + "bad_collapsed_image_both_space", + source_file_name=f"{source_path}bad_collapsed_image_both_space.md", + source_file_contents="""this is not ![ a proper ][] link [ a proper ]: /url -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not ![a proper][] link [ a proper ]: /url -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md039_good_shortcut_image(): - """ - Test to make sure this rule does not trigger with a document that - contains a shortcut image with no space on either side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "good_shortcut_image.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_md039_bad_shortcut_image_both_space(): - """ - Test to make sure this rule does trigger with a document that - contains a shortcut image with spaces on both sides of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md039", "bad_shortcut_image_both_space.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:2:1: MD039: Spaces inside link text (no-space-in-links)" - ) - - 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_md039_bad_shortcut_image_both_space_fix(): - """ - Test to make sure this rule does trigger with a document that - contains an inline link with space on the right side of the link label. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_shortcut_image_both_space.md" - ) as temp_source_path: - original_file_contents = """this is not +""", + ), + pluginRuleTest( + "good_shortcut_image", + source_file_name=f"{source_path}good_shortcut_image.md", + ), + pluginRuleTest( + "bad_shortcut_image_both_space", + source_file_name=f"{source_path}bad_shortcut_image_both_space.md", + source_file_contents="""this is not ![ a proper ] link [ a proper ]: /url -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - - expected_file_contents = """this is not +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:2:1: MD039: Spaces inside link text (no-space-in-links) +""", + fix_expected_file_contents="""this is not ![a proper] link [ a proper ]: /url -""" +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md039_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md039") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md039_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) diff --git a/test/rules/test_md047.py b/test/rules/test_md047.py index a175a08ff..064a7a739 100644 --- a/test/rules/test_md047.py +++ b/test/rules/test_md047.py @@ -2,314 +2,79 @@ Module to provide tests related to the MD047 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import ( - assert_file_is_as_expected, - copy_to_temp_file, - read_contents_of_text_file, +from test.rules.utils import ( + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginRuleTest, ) import pytest - -@pytest.mark.rules -def test_md047_all_samples(): - """ - Test to make sure we get the expected behavior after scanning the files in the - test/resources/rules/md047 directory. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join("test", "resources", "rules", "md047") + os.sep - supplied_arguments = ["scan", source_path] - - expected_return_code = 1 - expected_output = ( - f"{source_path}end_with_no_blank_line.md:3:41: " - + "MD047: Each file should end with a single newline character. " - + "(single-trailing-newline)\n" - + f"{source_path}end_with_no_blank_line_and_spaces.md:4:2: " - + "MD047: Each file should end with a single newline character. " - + "(single-trailing-newline)\n" - ) - 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_md047_good_end_with_blank_line(): - """ - Test to make sure this rule does not trigger with a document that - properly ends with a blank line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md047", "end_with_blank_line.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_md047_good_end_with_blank_line_fix(): - """ - Test to make sure this rule does not trigger with a document that - properly ends with a blank line. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join("test", "resources", "rules", "md047", "end_with_blank_line.md") - ) as temp_source_path: - supplied_arguments = ["-x-fix", "scan", temp_source_path] - - expected_return_code = 0 - expected_output = "" - expected_error = "" - expected_file_contents = read_contents_of_text_file(temp_source_path) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md047_bad_end_with_no_blank_line(): - """ - Test to make sure this rule does trigger with a document that - does not end with a blank line. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md047", "end_with_no_blank_line.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:41: " - + "MD047: Each file should end with a single newline character. (single-trailing-newline)\n" - ) - 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_md047_bad_end_with_no_blank_line_fix(): - """ - Test to make sure this rule does trigger with a document that - does not end with a blank line. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join("test", "resources", "rules", "md047", "end_with_no_blank_line.md") - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = read_contents_of_text_file(temp_source_path) + "\n" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md047_bad_end_with_blank_line_containing_spaces(): - """ - Test to make sure this rule does trigger with a document that - ends with a line that is only whitespace. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md047", "end_with_no_blank_line_and_spaces.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:2: " - + "MD047: Each file should end with a single newline character. (single-trailing-newline)\n" - ) - 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_md047_bad_end_with_blank_line_containing_spaces_fix(): - """ - Test to make sure this rule does trigger with a document that - ends with a line that is only whitespace. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md047", - "end_with_no_blank_line_and_spaces.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = read_contents_of_text_file(temp_source_path) + "\n" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md047_bad_conflicting_changes_at_end_of_file(): - """ - Test to make sure that only one plugin can make a change to the last line. - """ - - # Arrange - scanner = MarkdownScanner() - plugin_path = os.path.join( - "test", "resources", "plugins", "bad", "bad_update_last_line.py" - ) - with copy_to_temp_file( - os.path.join( - "test", - "resources", - "rules", - "md047", - "end_with_no_blank_line_and_spaces.md", - ) - ) as temp_source_path: - supplied_arguments = [ - "-x-fix", - "--add-plugin", - plugin_path, - "scan", - temp_source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = """BadPluginError encountered while scanning '{path}': -Plugin id 'MDE003' had a critical failure during the 'completed_file' action.""".replace( - "{path}", temp_source_path - ) - - # 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_md047_bad_end_with_no_blank_line_fix_and_debug(): - """ - Test to make sure this rule does trigger with a document that - does not end with a blank line. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - os.path.join("test", "resources", "rules", "md047", "end_with_no_blank_line.md") - ) as temp_source_path: - supplied_arguments = [ - "--disable-rules", - "md009", - "-x-fix-debug", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = """md010-before:# This is a test: +source_path = os.path.join("test", "resources", "rules", "md047") + os.sep + +scanTests = [ + pluginRuleTest( + "good_end_with_blank_line", + source_file_name=f"{source_path}end_with_blank_line.md", + ), + pluginRuleTest( + "bad_end_with_no_blank_line", + source_file_name=f"{source_path}end_with_no_blank_line.md", + source_file_contents="""# This is a test + +The line after this line should be blank.""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:41: MD047: Each file should end with a single newline character. (single-trailing-newline) +""", + fix_expected_file_contents="""# This is a test + +The line after this line should be blank. +""", + ), + pluginRuleTest( + "bad_end_with_blank_line_containing_spaces", + source_file_name=f"{source_path}end_with_no_blank_line_and_spaces.md", + source_file_contents="""# This is a test + +The line after this line is blank, but contains two spaces. +\a\a""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:2: MD047: Each file should end with a single newline character. (single-trailing-newline) +""", + fix_expected_file_contents="""# This is a test + +The line after this line is blank, but contains two spaces. +\a\a +""".replace( + "\a", " " + ), + ), + pluginRuleTest( + "bad_end_with_no_blank_line_fix_and_debug", + source_file_name=f"{source_path}end_with_no_blank_line.md", + use_fix_debug=True, + source_file_contents="""# This is a test + +The line after this line should be blank.""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:41: MD047: Each file should end with a single newline character. (single-trailing-newline) +""", + fix_expected_file_contents="""# This is a test + +The line after this line should be blank. +""", + fix_expected_output="""md009-before:# This is a test: +md010-before:# This is a test: md047-before:# This is a test: nl-ltw:# This is a test\\n: +md009-before:: md010-before:: md047-before:: nl-ltw:\\n: +md009-before:The line after this line should be blank.: md010-before:The line after this line should be blank.: md047-before:The line after this line should be blank.: was_newline_added_at_end_of_file=False @@ -319,17 +84,74 @@ def test_md047_bad_end_with_no_blank_line_fix_and_debug(): nl-ltw:The line after this line should be blank.: cf-ltw:\\n: FixLineRecord(source='completed_file', line_number=4, plugin_id='md047') -Fixed: {path}""".replace( - "{path}", temp_source_path - ) - expected_error = "" - expected_file_contents = read_contents_of_text_file(temp_source_path) + "\n" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +Fixed: {temp_source_path}""", + ), + pluginRuleTest( + "bad_conflicting_changes_at_end_of_file", + add_plugin_path=os.path.join( + "test", "resources", "plugins", "bad", "bad_update_last_line.py" + ), + source_file_name=f"{source_path}end_with_no_blank_line_and_spaces.md", + source_file_contents="""# This is a test + +The line after this line is blank, but contains two spaces. +\a\a""".replace( + "\a", " " + ), + scan_expected_return_code=1, + scan_expected_output="{temp_source_path}:4:2: MD047: Each file should end with a single newline character. (single-trailing-newline)", + fix_expected_file_contents="""# This is a test + +The line after this line is blank, but contains two spaces. +\a\a""".replace( + "\a", " " + ), + fix_expected_return_code=1, + fix_expected_output="", + fix_expected_error="""BadPluginError encountered while scanning '{temp_source_path}': +Plugin id 'MDE003' had a critical failure during the 'completed_file' action.""", + ), + pluginRuleTest( + "mix_md047_md010", + source_file_contents="""item\t1""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:5: MD010: Hard tabs [Column: 5] (no-hard-tabs) +{temp_source_path}:1:6: MD047: Each file should end with a single newline character. (single-trailing-newline) +""", + fix_expected_file_contents="""item 1 +""", + ), + pluginRuleTest( + "mix_md047_md019", + source_file_contents="""# Heading 1 + +a line of 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) +{temp_source_path}:3:14: MD047: Each file should end with a single newline character. (single-trailing-newline)""", + fix_expected_file_contents="""# Heading 1 + +a line of text +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + + +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md047_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md047") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md047_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) diff --git a/test/rules/test_md048.py b/test/rules/test_md048.py index abcb42585..e3d146b9f 100644 --- a/test/rules/test_md048.py +++ b/test/rules/test_md048.py @@ -2,202 +2,53 @@ Module to provide tests related to the MD048 rule. """ import os -from test.markdown_scanner import MarkdownScanner -from test.utils import assert_file_is_as_expected, copy_to_temp_file +from test.rules.utils import ( + execute_configuration_test, + execute_fix_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginRuleTest, +) import pytest source_path = os.path.join("test", "resources", "rules", "md048") + os.sep - -@pytest.mark.rules -def test_md048_bad_configuration_style(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with an integer that is not a string. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "good_both_tildes.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=$#1", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md048.style' must be of type 'str'." - ) - - # 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_md048_bad_configuration_style_bad(): - """ - Test to verify that a configuration error is thrown when supplying the - style value with a string that is not valid. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "good_both_tildes.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=not-matching", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md048.style' is not valid: Allowable values: ['consistent', 'tilde', 'backtick']" - ) - - # 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_md048_good_fenced_tildes_with_consistent(): - """ - Test to make sure this rule does not trigger with a document that - contains fenced code blocks with tildes and consistent configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "good_fenced_tildes.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=consistent", - "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_md048_good_fenced_backticks_with_consistent(): - """ - Test to make sure this rule does not trigger with a document that - contains fenced code blocks with backticks and consistent configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "good_fenced_backticks.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=consistent", - "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_md048_bad_fenced_backticks_and_tildes_with_consistent(): - """ - Test to make sure this rule does trigger with a document that - contains fenced code blocks with tildes and backticks and consistent configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "bad_fenced_backticks_and_tildes.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=consistent", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:1: " - + "MD048: Code fence style " - + "[Expected: backtick; Actual: tilde] (code-fence-style)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - - -source_path = os.path.join("test", "resources", "rules", "md048") + os.sep - - -@pytest.mark.rules -def test_md048_bad_fenced_backticks_and_tildes_with_consistent_fix(): - """ - Test to make sure this rule does trigger with a document that - contains fenced code blocks with tildes and backticks and consistent configuration. - """ - - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_fenced_backticks_and_tildes.md" - ) as temp_source_path: - original_file_contents = """```Python +configTests = [ + pluginConfigErrorTest( + "invalid_style_type", + use_strict_config=True, + set_args=["plugins.md048.style=$#1"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md048.style' must be of type 'str'.""", + ), + pluginConfigErrorTest( + "invalid_style", + use_strict_config=True, + set_args=["plugins.md048.style=not-matching"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md048.style' is not valid: Allowable values: ['consistent', 'tilde', 'backtick']""", + ), +] + + +scanTests = [ + pluginRuleTest( + "good_fenced_tildes_with_consistent", + source_file_name=f"{source_path}good_fenced_tildes.md", + set_args=["plugins.md048.style=consistent"], + ), + pluginRuleTest( + "good_fenced_backticks_with_consistent", + source_file_name=f"{source_path}good_fenced_backticks.md", + set_args=["plugins.md048.style=consistent"], + ), + pluginRuleTest( + "bad_fenced_backticks_and_tildes_with_consistent", + source_file_name=f"{source_path}bad_fenced_backticks_and_tildes.md", + set_args=["plugins.md048.style=consistent"], + source_file_contents="""```Python def test(): print("test") ``` @@ -206,21 +57,11 @@ def test(): def test(): print("test") ~~~ -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md048.style=consistent", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = """```Python +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:6:1: MD048: Code fence style [Expected: backtick; Actual: tilde] (code-fence-style) +""", + fix_expected_file_contents="""```Python def test(): print("test") ``` @@ -229,138 +70,47 @@ def test(): def test(): print("test") ``` -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md048_good_fenced_backticks_with_backticks(): - """ - Test to make sure this rule does not trigger with a document that - contains fenced code blocks with backticks and backtick configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "good_fenced_backticks.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=backtick", - "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_md048_good_fenced_tildes_with_backticks(): - """ - Test to make sure this rule does trigger with a document that - contains fenced code blocks with backticks and tilde configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "good_fenced_tildes.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=backtick", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD048: Code fence style " - + "[Expected: backtick; Actual: tilde] (code-fence-style)\n" - + f"{source_path}:6:1: " - + "MD048: Code fence style " - + "[Expected: backtick; Actual: tilde] (code-fence-style)" - ) - 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_md048_bad_fenced_backticks_and_tildes_with_backticks(): - """ - Test to make sure this rule does not trigger with a document that - contains fenced code blocks with backticks and tildes and backtick configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "bad_fenced_backticks_and_tildes.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=backtick", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:6:1: " - + "MD048: Code fence style " - + "[Expected: backtick; Actual: tilde] (code-fence-style)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - +""", + ), + pluginRuleTest( + "good_fenced_backticks_with_backticks", + source_file_name=f"{source_path}good_fenced_backticks.md", + set_args=["plugins.md048.style=backtick"], + ), + pluginRuleTest( + "bad_fenced_tildes_with_backticks", + source_file_name=f"{source_path}good_fenced_tildes.md", + set_args=["plugins.md048.style=backtick"], + source_file_contents="""~~~Python +def test(): + print("test") +~~~ -@pytest.mark.rules -def test_md048_bad_fenced_backticks_and_tildes_with_backticks_fix(): - """ - Test to make sure this rule does not trigger with a document that - contains fenced code blocks with backticks and tildes and backtick configuration. - """ +~~~Python +def test(): + print("test") +~~~ +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD048: Code fence style [Expected: backtick; Actual: tilde] (code-fence-style) +{temp_source_path}:6:1: MD048: Code fence style [Expected: backtick; Actual: tilde] (code-fence-style) +""", + fix_expected_file_contents="""```Python +def test(): + print("test") +``` - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_fenced_backticks_and_tildes.md" - ) as temp_source_path: - original_file_contents = """```Python +```Python +def test(): + print("test") +``` +""", + ), + pluginRuleTest( + "bad_fenced_backticks_and_tildes_with_backticks", + source_file_name=f"{source_path}bad_fenced_backticks_and_tildes.md", + set_args=["plugins.md048.style=backtick"], + source_file_contents="""```Python def test(): print("test") ``` @@ -369,21 +119,11 @@ def test(): def test(): print("test") ~~~ -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md048.style=backtick", - "-x-fix", - "scan", - temp_source_path, - ] - - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = """```Python +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:6:1: MD048: Code fence style [Expected: backtick; Actual: tilde] (code-fence-style) +""", + fix_expected_file_contents="""```Python def test(): print("test") ``` @@ -392,161 +132,60 @@ def test(): def test(): print("test") ``` -""" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) - - -@pytest.mark.rules -def test_md048_good_fenced_tildes_with_tilde(): - """ - Test to make sure this rule does not trigger with a document that - contains fenced code blocks with tildes and tilde configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "good_fenced_tildes.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=tilde", - "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_md048_good_fenced_backticks_with_tilde(): - """ - Test to make sure this rule does not trigger with a document that - contains fenced code blocks with backticks and tilde configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "good_fenced_backticks.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=tilde", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD048: Code fence style " - + "[Expected: tilde; Actual: backtick] (code-fence-style)\n" - + f"{source_path}:6:1: " - + "MD048: Code fence style " - + "[Expected: tilde; Actual: backtick] (code-fence-style)" - ) - 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_md048_bad_fenced_backticks_and_tildes_with_indented(): - """ - Test to make sure this rule does trigger with a document that - contains fenced code blocks with backticks and tildes and tilde configuration. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md048", "bad_fenced_backticks_and_tildes.md" - ) - supplied_arguments = [ - "--set", - "plugins.md048.style=tilde", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:1:1: " - + "MD048: Code fence style " - + "[Expected: tilde; Actual: backtick] (code-fence-style)" - ) - 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_md048_bad_fenced_backticks_and_tildes_with_indented_fix(): - """ - Test to make sure this rule does trigger with a document that - contains fenced code blocks with backticks and tildes and tilde configuration. - """ +""", + ), + pluginRuleTest( + "good_fenced_tildes_with_tilde", + source_file_name=f"{source_path}good_fenced_tildes.md", + set_args=["plugins.md048.style=tilde"], + ), + pluginRuleTest( + "bad_fenced_backticks_with_tilde", + source_file_name=f"{source_path}good_fenced_backticks.md", + set_args=["plugins.md048.style=tilde"], + source_file_contents="""```Python +def test(): + print("test") +``` - # Arrange - scanner = MarkdownScanner() - with copy_to_temp_file( - source_path + "bad_fenced_backticks_and_tildes.md" - ) as temp_source_path: - original_file_contents = """```Python +```Python def test(): print("test") ``` +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD048: Code fence style [Expected: tilde; Actual: backtick] (code-fence-style) +{temp_source_path}:6:1: MD048: Code fence style [Expected: tilde; Actual: backtick] (code-fence-style) +""", + fix_expected_file_contents="""~~~Python +def test(): + print("test") +~~~ ~~~Python def test(): print("test") ~~~ -""" - assert_file_is_as_expected(temp_source_path, original_file_contents) - - supplied_arguments = [ - "--set", - "plugins.md048.style=tilde", - "-x-fix", - "scan", - temp_source_path, - ] +""", + ), + pluginRuleTest( + "bad_fenced_backticks_and_tildes_with_indented", + source_file_name=f"{source_path}bad_fenced_backticks_and_tildes.md", + set_args=["plugins.md048.style=tilde"], + source_file_contents="""```Python +def test(): + print("test") +``` - expected_return_code = 3 - expected_output = f"Fixed: {temp_source_path}" - expected_error = "" - expected_file_contents = """~~~Python +~~~Python +def test(): + print("test") +~~~ +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD048: Code fence style [Expected: tilde; Actual: backtick] (code-fence-style) +""", + fix_expected_file_contents="""~~~Python def test(): print("test") ~~~ @@ -555,13 +194,34 @@ def test(): def test(): print("test") ~~~ -""" +""", + ), +] +fixTests = [] +for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - assert_file_is_as_expected(temp_source_path, expected_file_contents) +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md048_scan(test: pluginRuleTest) -> None: + """ + Execute a parameterized scan test for plugin md001. + """ + execute_scan_test(test, "md048") + + +@pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) +def test_md048_fix(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_fix_test(test) + + +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md048_config(test: pluginRuleTest) -> None: + """ + Execute a parameterized fix test for plugin md001. + """ + execute_configuration_test(test, f"{source_path}bad_fenced_backticks_and_tildes.md") diff --git a/test/rules/test_plugin_manager.py b/test/rules/test_plugin_manager.py index 5fbda1a40..f388f3b60 100644 --- a/test/rules/test_plugin_manager.py +++ b/test/rules/test_plugin_manager.py @@ -1279,57 +1279,62 @@ def test_markdown_with_plugins_list_only(): expected_return_code = 0 expected_output = """ - ID NAMES ENABLED ENABLED VERSION - (DEFAULT) (CURRENT) - - md001 heading-increment, header-increment True True 0.5.0 - md002 first-heading-h1, first-header-h1 False False 0.5.0 - md003 heading-style, header-style True True 0.5.0 - md004 ul-style True True 0.5.0 - md005 list-indent True True 0.5.0 - md006 ul-start-left False False 0.5.0 - md007 ul-indent True True 0.5.0 - md009 no-trailing-spaces True True 0.5.0 - md010 no-hard-tabs True True 0.5.0 - md011 no-reversed-links True True 0.5.0 - md012 no-multiple-blanks True True 0.5.0 - md013 line-length True True 0.5.0 - md014 commands-show-output True True 0.5.0 - md018 no-missing-space-atx True True 0.5.0 - md019 no-multiple-space-atx True True 0.5.0 - md020 no-missing-space-closed-atx True True 0.5.0 - md021 no-multiple-space-closed-atx True True 0.5.0 - md022 blanks-around-headings, blanks-around True True 0.5.0 - -headers - md023 heading-start-left, header-start-left True True 0.5.0 - md024 no-duplicate-heading, no-duplicate-he True True 0.5.0 - ader - md025 single-title, single-h1 True True 0.5.0 - md026 no-trailing-punctuation True True 0.5.0 - md027 no-multiple-space-blockquote True True 0.5.0 - md028 no-blanks-blockquote True True 0.5.0 - md029 ol-prefix True True 0.5.0 - md030 list-marker-space True True 0.5.0 - md031 blanks-around-fences True True 0.5.0 - md032 blanks-around-lists True True 0.5.0 - md033 no-inline-html True True 0.5.1 - md034 no-bare-urls True True 0.5.0 - md035 hr-style True True 0.5.0 - md036 no-emphasis-as-heading, no-emphasis-a True True 0.5.0 - s-header - md037 no-space-in-emphasis True True 0.5.0 - md038 no-space-in-code True True 0.5.0 - md039 no-space-in-links True True 0.5.0 - md040 fenced-code-language True True 0.5.0 - md041 first-line-heading, first-line-h1 True True 0.5.0 - md042 no-empty-links True True 0.5.0 - md043 required-headings, required-headers True True 0.5.0 - md044 proper-names True True 0.5.0 - md045 no-alt-text True True 0.5.0 - md046 code-block-style True True 0.5.0 - md047 single-trailing-newline True True 0.5.0 - md048 code-fence-style True True 0.5.0 - pml100 disallowed-html False False 0.5.0 + ID NAMES ENABLED ENABLED VERSION FIX + (DEFAULT) (CURRENT) + + md001 heading-increment, header-incr True True 0.5.0 Yes + ement + md002 first-heading-h1, first-header False False 0.5.0 No + -h1 + md003 heading-style, header-style True True 0.5.0 No + md004 ul-style True True 0.5.0 Yes + md005 list-indent True True 0.5.0 Yes + md006 ul-start-left False False 0.5.0 Yes + md007 ul-indent True True 0.5.0 Yes + md009 no-trailing-spaces True True 0.5.0 Yes + md010 no-hard-tabs True True 0.5.0 Yes + md011 no-reversed-links True True 0.5.0 No + md012 no-multiple-blanks True True 0.5.0 No + md013 line-length True True 0.5.0 No + md014 commands-show-output True True 0.5.0 No + md018 no-missing-space-atx True True 0.5.0 No + md019 no-multiple-space-atx True True 0.5.0 Yes + md020 no-missing-space-closed-atx True True 0.5.0 No + md021 no-multiple-space-closed-atx True True 0.5.0 Yes + md022 blanks-around-headings, blanks True True 0.5.0 No + -around-headers + md023 heading-start-left, header-sta True True 0.5.0 Yes + rt-left + md024 no-duplicate-heading, no-dupli True True 0.5.0 No + cate-header + md025 single-title, single-h1 True True 0.5.0 No + md026 no-trailing-punctuation True True 0.5.0 No + md027 no-multiple-space-blockquote True True 0.5.0 Yes + md028 no-blanks-blockquote True True 0.5.0 No + md029 ol-prefix True True 0.5.0 Yes + md030 list-marker-space True True 0.5.0 Yes + md031 blanks-around-fences True True 0.5.0 No + md032 blanks-around-lists True True 0.5.0 No + md033 no-inline-html True True 0.5.1 No + md034 no-bare-urls True True 0.5.0 No + md035 hr-style True True 0.5.0 Yes + md036 no-emphasis-as-heading, no-emp True True 0.5.0 No + hasis-as-header + md037 no-space-in-emphasis True True 0.5.0 Yes + md038 no-space-in-code True True 0.5.0 Yes + md039 no-space-in-links True True 0.5.0 Yes + md040 fenced-code-language True True 0.5.0 No + md041 first-line-heading, first-line True True 0.5.0 No + -h1 + md042 no-empty-links True True 0.5.0 No + md043 required-headings, required-he True True 0.5.0 No + aders + md044 proper-names True True 0.5.0 No + md045 no-alt-text True True 0.5.0 No + md046 code-block-style True True 0.5.0 No + md047 single-trailing-newline True True 0.5.0 Yes + md048 code-fence-style True True 0.5.0 Yes + pml100 disallowed-html False False 0.5.0 No """ expected_error = "" @@ -1357,58 +1362,64 @@ def test_markdown_with_plugins_list_only_all(): expected_return_code = 0 expected_output = """ - ID NAMES ENABLED ENABLED VERSION - (DEFAULT) (CURRENT) - - md001 heading-increment, header-increment True True 0.5.0 - md002 first-heading-h1, first-header-h1 False False 0.5.0 - md003 heading-style, header-style True True 0.5.0 - md004 ul-style True True 0.5.0 - md005 list-indent True True 0.5.0 - md006 ul-start-left False False 0.5.0 - md007 ul-indent True True 0.5.0 - md009 no-trailing-spaces True True 0.5.0 - md010 no-hard-tabs True True 0.5.0 - md011 no-reversed-links True True 0.5.0 - md012 no-multiple-blanks True True 0.5.0 - md013 line-length True True 0.5.0 - md014 commands-show-output True True 0.5.0 - md018 no-missing-space-atx True True 0.5.0 - md019 no-multiple-space-atx True True 0.5.0 - md020 no-missing-space-closed-atx True True 0.5.0 - md021 no-multiple-space-closed-atx True True 0.5.0 - md022 blanks-around-headings, blanks-around True True 0.5.0 - -headers - md023 heading-start-left, header-start-left True True 0.5.0 - md024 no-duplicate-heading, no-duplicate-he True True 0.5.0 - ader - md025 single-title, single-h1 True True 0.5.0 - md026 no-trailing-punctuation True True 0.5.0 - md027 no-multiple-space-blockquote True True 0.5.0 - md028 no-blanks-blockquote True True 0.5.0 - md029 ol-prefix True True 0.5.0 - md030 list-marker-space True True 0.5.0 - md031 blanks-around-fences True True 0.5.0 - md032 blanks-around-lists True True 0.5.0 - md033 no-inline-html True True 0.5.1 - md034 no-bare-urls True True 0.5.0 - md035 hr-style True True 0.5.0 - md036 no-emphasis-as-heading, no-emphasis-a True True 0.5.0 - s-header - md037 no-space-in-emphasis True True 0.5.0 - md038 no-space-in-code True True 0.5.0 - md039 no-space-in-links True True 0.5.0 - md040 fenced-code-language True True 0.5.0 - md041 first-line-heading, first-line-h1 True True 0.5.0 - md042 no-empty-links True True 0.5.0 - md043 required-headings, required-headers True True 0.5.0 - md044 proper-names True True 0.5.0 - md045 no-alt-text True True 0.5.0 - md046 code-block-style True True 0.5.0 - md047 single-trailing-newline True True 0.5.0 - md048 code-fence-style True True 0.5.0 - md999 debug-only False False 0.0.0 - pml100 disallowed-html False False 0.5.0 + ID NAMES ENABLED ENABLED VERSION FIX + (DEFAULT) (CURRENT) + + md001 heading-increment, header-incr True True 0.5.0 Yes + ement + md002 first-heading-h1, first-header False False 0.5.0 No + -h1 + md003 heading-style, header-style True True 0.5.0 No + md004 ul-style True True 0.5.0 Yes + md005 list-indent True True 0.5.0 Yes + md006 ul-start-left False False 0.5.0 Yes + md007 ul-indent True True 0.5.0 Yes + md009 no-trailing-spaces True True 0.5.0 Yes + md010 no-hard-tabs True True 0.5.0 Yes + md011 no-reversed-links True True 0.5.0 No + md012 no-multiple-blanks True True 0.5.0 No + md013 line-length True True 0.5.0 No + md014 commands-show-output True True 0.5.0 No + md018 no-missing-space-atx True True 0.5.0 No + md019 no-multiple-space-atx True True 0.5.0 Yes + md020 no-missing-space-closed-atx True True 0.5.0 No + md021 no-multiple-space-closed-atx True True 0.5.0 Yes + md022 blanks-around-headings, blanks True True 0.5.0 No + -around-headers + md023 heading-start-left, header-sta True True 0.5.0 Yes + rt-left + md024 no-duplicate-heading, no-dupli True True 0.5.0 No + cate-header + md025 single-title, single-h1 True True 0.5.0 No + md026 no-trailing-punctuation True True 0.5.0 No + md027 no-multiple-space-blockquote True True 0.5.0 Yes + md028 no-blanks-blockquote True True 0.5.0 No + md029 ol-prefix True True 0.5.0 Yes + md030 list-marker-space True True 0.5.0 Yes + md031 blanks-around-fences True True 0.5.0 No + md032 blanks-around-lists True True 0.5.0 No + md033 no-inline-html True True 0.5.1 No + md034 no-bare-urls True True 0.5.0 No + md035 hr-style True True 0.5.0 Yes + md036 no-emphasis-as-heading, no-emp True True 0.5.0 No + hasis-as-header + md037 no-space-in-emphasis True True 0.5.0 Yes + md038 no-space-in-code True True 0.5.0 Yes + md039 no-space-in-links True True 0.5.0 Yes + md040 fenced-code-language True True 0.5.0 No + md041 first-line-heading, first-line True True 0.5.0 No + -h1 + md042 no-empty-links True True 0.5.0 No + md043 required-headings, required-he True True 0.5.0 No + aders + md044 proper-names True True 0.5.0 No + md045 no-alt-text True True 0.5.0 No + md046 code-block-style True True 0.5.0 No + md047 single-trailing-newline True True 0.5.0 Yes + md048 code-fence-style True True 0.5.0 Yes + md999 debug-only False False 0.0.0 No + pml100 disallowed-html False False 0.5.0 No + """ expected_error = "" @@ -1434,13 +1445,13 @@ def test_markdown_with_plugins_list_and_filter_by_id_ends_with_nine(): expected_return_code = 0 expected_output = """ - ID NAMES ENABLED ENABLED VERSION + ID NAMES ENABLED ENABLED VERSION FIX (DEFAULT) (CURRENT) - md009 no-trailing-spaces True True 0.5.0 - md019 no-multiple-space-atx True True 0.5.0 - md029 ol-prefix True True 0.5.0 - md039 no-space-in-links True True 0.5.0 + md009 no-trailing-spaces True True 0.5.0 Yes + md019 no-multiple-space-atx True True 0.5.0 Yes + md029 ol-prefix True True 0.5.0 Yes + md039 no-space-in-links True True 0.5.0 Yes """ expected_error = "" @@ -1488,20 +1499,24 @@ def test_markdown_with_plugins_list_and_filter_by_name_link(): expected_return_code = 0 expected_output = """ - ID NAMES ENABLED ENABLED VERSION - (DEFAULT) (CURRENT) - - md001 heading-increment, header-increment True True 0.5.0 - md002 first-heading-h1, first-header-h1 False False 0.5.0 - md003 heading-style, header-style True True 0.5.0 - md022 blanks-around-headings, blanks-around- True True 0.5.0 - headers - md023 heading-start-left, header-start-left True True 0.5.0 - md024 no-duplicate-heading, no-duplicate-hea True True 0.5.0 - der - md036 no-emphasis-as-heading, no-emphasis-as True True 0.5.0 - -header - md043 required-headings, required-headers True True 0.5.0 + ID NAMES ENABLED ENABLED VERSION FIX + (DEFAULT) (CURRENT) + + md001 heading-increment, header-incre True True 0.5.0 Yes + ment + md002 first-heading-h1, first-header- False False 0.5.0 No + h1 + md003 heading-style, header-style True True 0.5.0 No + md022 blanks-around-headings, blanks- True True 0.5.0 No + around-headers + md023 heading-start-left, header-star True True 0.5.0 Yes + t-left + md024 no-duplicate-heading, no-duplic True True 0.5.0 No + ate-header + md036 no-emphasis-as-heading, no-emph True True 0.5.0 No + asis-as-header + md043 required-headings, required-hea True True 0.5.0 No + ders """ expected_error = "" @@ -2033,34 +2048,6 @@ def test_markdown_fixed_issue_token_with_debug_and_file_debug_on(): ] expected_return_code = 3 - expected_output = """md009-before:# Heading 1: -md010-before:# Heading 1: -md047-before:# Heading 1: -nl-ltw:# Heading 1\\n: -md009-before:: -md010-before:: -md047-before:: -nl-ltw:\\n: -md009-before:## Heading 3: -md010-before:## Heading 3: -md047-before:## Heading 3: -nl-ltw:## Heading 3\\n: -md009-before:: -md010-before:: -md047-before:: -nl-ltw:\\n: -md009-before:We skipped out a 2nd level heading in this document: -md010-before:We skipped out a 2nd level heading in this document: -md047-before:We skipped out a 2nd level heading in this document: -nl-ltw:We skipped out a 2nd level heading in this document\\n: -md009-before:: -md010-before:: -md047-before:: -was_newline_added_at_end_of_file=True -fixed:We skipped out a 2nd level heading in this document\\n: -is_line_empty=True -was_modified=True -nl-ltw::""" expected_error = "" initial_file_contents = read_contents_of_text_file(temp_source_path) expected_file_contents = """# Heading 1 @@ -2085,27 +2072,13 @@ def test_markdown_fixed_issue_token_with_debug_and_file_debug_on(): std_out_split = execute_results.std_out.getvalue().splitlines() print(std_out_split) - first_section = std_out_split[:12] + first_section = std_out_split[:4] print(first_section) assert first_section[0] == "" assert first_section[1].startswith("--") and first_section[1].endswith("--") assert first_section[2] == initial_file_contents.replace("\n", "\\n") assert first_section[3] == "--" - assert ( - first_section[4] - == "BEFORE:[atx(3,1):3:0:]:[FixTokenRecord(token_to_fix='[atx(3,1):3:0:]', plugin_id='MD001', plugin_action='next_token', field_name='hash_count', field_value=2)]" - ) - assert ( - first_section[5] - == " AFTER:[atx(3,1):2:0:]:[FixTokenRecord(token_to_fix='[atx(3,1):2:0:]', plugin_id='MD001', plugin_action='next_token', field_name='hash_count', field_value=2)]" - ) - assert first_section[6] == "--" - assert first_section[7] == "" - assert first_section[8].startswith("--") and first_section[1].endswith("--") - assert first_section[9] == expected_file_contents.replace("\n", "\\n") - assert first_section[10] == "--" - assert first_section[11].startswith("scan: ") last_section = std_out_split[-8:] print(last_section) @@ -2118,15 +2091,15 @@ def test_markdown_fixed_issue_token_with_debug_and_file_debug_on(): assert last_section[6].startswith("Remove:") assert last_section[7] == f"Fixed: {temp_source_path}" - middle_section = std_out_split[12:-8] - print("-->") - print("\n".join(middle_section)) - print("<--") - split_output = expected_output.splitlines() - print(split_output) - assert len(middle_section) == len(split_output) - for i in range(0, len(split_output)): - assert middle_section[i] == split_output[i] + # middle_section = std_out_split[4:-8] + # print("-->") + # print("\n".join(middle_section)) + # print("<--") + # split_output = expected_output.splitlines() + # print(split_output) + # assert len(middle_section) == len(split_output) + # for i in range(0, len(split_output)): + # assert middle_section[i] == split_output[i] def test_markdown_plugins_wanting_to_fix_same_token(): diff --git a/test/rules/utils.py b/test/rules/utils.py new file mode 100644 index 000000000..8e29e7889 --- /dev/null +++ b/test/rules/utils.py @@ -0,0 +1,210 @@ +import os +from contextlib import contextmanager +from dataclasses import dataclass +from test.markdown_scanner import MarkdownScanner +from test.utils import ( + assert_file_is_as_expected, + assert_if_lists_different, + copy_to_temporary_file, + write_temporary_configuration, +) +from typing import Any, List, Optional + + +@dataclass +class pluginConfigErrorTest: + """ + Class to represent the testing needs of a plugin rule. + """ + + name: str + use_strict_config: bool + set_args: List[str] + expected_error: str + + +@dataclass +class pluginRuleTest: + """ + Class to represent the testing needs of a plugin rule. + """ + + name: str + source_file_name: Optional[str] = None + source_file_contents: Optional[str] = None + set_args: Optional[List[str]] = None + use_debug: bool = False + use_strict_config: bool = False + use_fix_debug: bool = False + disable_rules: str = "" + enable_rules: str = "" + scan_expected_return_code: int = 0 + scan_expected_output: str = "" + scan_expected_error: str = "" + fix_expected_return_code: int = 3 + fix_expected_file_contents: str = "" + fix_expected_output: Optional[str] = None + fix_expected_error: str = "" + add_plugin_path: str = "" + is_mix_test: bool = True + + +def id_test_plug_rule_fn(val: Any) -> str: + """ + Id functions to allow for parameterization to be used more meaningfully. + """ + if isinstance(val, (pluginRuleTest, pluginConfigErrorTest)): + return val.name + raise AssertionError() + + +def build_fix_and_clash_lists(scanTests: List[pluginRuleTest]): + fixTests: List[pluginRuleTest] = [] + clashTests: List[pluginRuleTest] = [] + for i in scanTests: + if i.fix_expected_file_contents: + fixTests.append(i) + for i in fixTests: + if i.disable_rules: + clashTests.append(i) + return fixTests, clashTests + + +@contextmanager +def build_arguments( + test: pluginRuleTest, is_fix: bool, skip_disabled_rules: bool = False +): + temp_source_path = None + try: + if test.source_file_name: + temp_source_path = copy_to_temporary_file(test.source_file_name) + if test.source_file_contents: + assert_file_is_as_expected(temp_source_path, test.source_file_contents) + else: + assert test.source_file_contents + temp_source_path = write_temporary_configuration( + test.source_file_contents, file_name_suffix=".md" + ) + + supplied_arguments = [] + if test.use_debug: + supplied_arguments.append("--stack-trace") + if test.add_plugin_path: + supplied_arguments.extend(("--add-plugin", test.add_plugin_path)) + if test.use_strict_config: + supplied_arguments.append("--strict-config") + if test.set_args: + for next_set_arg in test.set_args: + supplied_arguments.extend(("--set", next_set_arg)) + if test.enable_rules: + supplied_arguments.extend(("--enable-rules", test.enable_rules)) + if test.disable_rules and not skip_disabled_rules: + supplied_arguments.extend(("--disable-rules", test.disable_rules)) + + if is_fix: + if test.use_fix_debug: + supplied_arguments.append("-x-fix-debug"), + supplied_arguments.extend(("-x-fix", "scan", temp_source_path)) + else: + supplied_arguments.extend(("scan", temp_source_path)) + + yield temp_source_path, supplied_arguments + finally: + if temp_source_path: + os.remove(temp_source_path) + + +def execute_scan_test(test: pluginRuleTest, host_rule_id: str): + scanner = MarkdownScanner() + with build_arguments(test, False) as (temp_source_path, supplied_arguments): + expected_return_code = test.scan_expected_return_code + expected_output = test.scan_expected_output.replace( + "{temp_source_path}", temp_source_path + ) + expected_error = test.scan_expected_error + + # Act + execute_results = scanner.invoke_main(arguments=supplied_arguments) + + # Assert + execute_results.assert_results( + expected_output, expected_error, expected_return_code + ) + if test.disable_rules and not test.is_mix_test: + with build_arguments(test, False, skip_disabled_rules=True) as ( + temp_source_path, + supplied_arguments, + ): + execute_results = scanner.invoke_main(arguments=supplied_arguments) + assert execute_results.return_code == 1 or execute_results.return_code == 0 + assert execute_results.std_err.getvalue() == "" + disabled_rules = test.disable_rules.lower().split(",") + + found_rules = [] + for next_line in execute_results.std_out.getvalue().split("\n"): + if not next_line: + continue + assert next_line.startswith(temp_source_path) + split_line = next_line[len(temp_source_path) + 1 :].split(":") + assert len(split_line) > 3 + oo = split_line[2].strip().lower() + if oo != host_rule_id and oo not in found_rules: + found_rules.append(oo) + + disabled_rules.sort() + found_rules.sort() + assert_if_lists_different(disabled_rules, found_rules) + + +def execute_fix_test(test: pluginRuleTest): + scanner = MarkdownScanner() + with build_arguments(test, True) as (temp_source_path, supplied_arguments): + expected_return_code = test.fix_expected_return_code + if test.fix_expected_output is not None: + expected_output = test.fix_expected_output.replace( + "{temp_source_path}", temp_source_path + ) + else: + expected_output = f"Fixed: {temp_source_path}" + if test.fix_expected_error: + expected_error = test.fix_expected_error.replace( + "{temp_source_path}", temp_source_path + ) + else: + expected_error = "" + expected_file_contents = test.fix_expected_file_contents + + # Act + execute_results = scanner.invoke_main(arguments=supplied_arguments) + + # Assert + execute_results.assert_results( + expected_output, expected_error, expected_return_code + ) + assert_file_is_as_expected(temp_source_path, expected_file_contents) + + +def execute_configuration_test(test: pluginConfigErrorTest, file_to_use: str): + scanner = MarkdownScanner() + + temp_source_path = copy_to_temporary_file(file_to_use) + supplied_arguments = [] + if test.use_strict_config: + supplied_arguments.append("--strict-config") + if test.set_args: + for next_set_arg in test.set_args: + supplied_arguments.extend(("--set", next_set_arg)) + + supplied_arguments.extend(("scan", temp_source_path)) + + expected_return_code = 1 + expected_output = "" + expected_error = test.expected_error + + # Act + execute_results = scanner.invoke_main(arguments=supplied_arguments) + + # Assert + execute_results.assert_results( + expected_output, expected_error, expected_return_code + ) diff --git a/test/tokens/test_block_quote_markdown_token.py b/test/tokens/test_block_quote_markdown_token.py new file mode 100644 index 000000000..c17e73c69 --- /dev/null +++ b/test/tokens/test_block_quote_markdown_token.py @@ -0,0 +1,23 @@ +from test.tokens.mock_plugin_modify_context import MockPluginModifyContext + +from pymarkdown.general.position_marker import PositionMarker +from pymarkdown.tokens.block_quote_markdown_token import BlockQuoteMarkdownToken + + +def test_block_quote_markdown_token_modify_with_bad_name(): + """ + Test to make sure that try to change this token with a bad name fails. + """ + + # Arrange + modification_context = MockPluginModifyContext() + original_token = BlockQuoteMarkdownToken( + position_marker=PositionMarker(1, 1, 1), + extracted_whitespace="", + ) + + # Act + did_modify = original_token.modify_token(modification_context, "bad_name", "") + + # Assert + assert not did_modify diff --git a/test/utils.py b/test/utils.py index 7f49db335..7f5bee53d 100644 --- a/test/utils.py +++ b/test/utils.py @@ -127,7 +127,7 @@ def assert_if_lists_different(expected_tokens, actual_tokens): print(f"parsed_tokens : {ParserHelper.make_value_visible(actual_tokens)}") assert len(expected_tokens) == len( actual_tokens - ), f"List lengths are not the same: ({len(expected_tokens)}) vs ({len(actual_tokens)})" + ), f"List lengths are not the same: ({len(expected_tokens)}:{expected_tokens}) vs ({len(actual_tokens)}:{actual_tokens})" print("---") for element_index, next_expected_token in enumerate(expected_tokens):