Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

https://github.com/jackdewinter/pymarkdown/issues/1233 #1241

Merged
merged 7 commits into from
Oct 23, 2024

Conversation

jackdewinter
Copy link
Owner

@jackdewinter jackdewinter commented Oct 23, 2024

closes #1233
closes #1234
closes #1235

Summary by Sourcery

Fix block quote handling in container reduction and add comprehensive tests for nested structures with fenced code blocks.

Bug Fixes:

  • Fix the issue where block quotes were not properly closed when reducing containers, ensuring the correct number of block quote tokens are generated.

Tests:

  • Add extensive test cases for nested block quotes and lists with fenced code blocks, covering various scenarios including thematic breaks, blank lines, and different indentation levels.

Copy link
Contributor

sourcery-ai bot commented Oct 23, 2024

Reviewer's Guide by Sourcery

This pull request addresses multiple issues related to handling nested block quotes, lists, and fenced code blocks in Markdown parsing. The changes primarily affect the test suite, adding numerous new test cases to cover various edge cases and scenarios. The main implementation changes are in the container_helper.py file, modifying how nested block quotes and lists are processed.

Class diagram for test cases in nested_three

classDiagram
    class TestMarkdownNestedThreeBlockUnorderedBlock {
        +test_nested_three_block_unordered_block_fenced_empty_with_thematics()
        +test_nested_three_block_unordered_block_fenced_empty_with_blanks_with_thematics()
        +test_nested_three_block_unordered_block_fenced_with_thematics()
        +test_nested_three_block_unordered_block_fenced_with_blanks_with_thematics()
        +test_nested_three_block_unordered_block_fenced_with_text_before_with_thematics()
        +test_nested_three_block_unordered_block_fenced_with_blanks_with_text_before_with_thematics()
        +test_nested_three_block_unordered_block_fenced_with_text_after_with_thematics()
        +test_nested_three_block_unordered_block_fenced_with_blanks_with_text_after_with_thematics()
        +test_nested_three_block_unordered_block_fenced_multiline_with_thematics()
        +test_nested_three_block_unordered_block_thematics_around_text_lines()
        +test_nested_three_block_unordered_block_thematics_around_blanks_around_text_lines()
        +test_nested_three_block_unordered_block_thematics_around_text_lines_with_text_after()
        +test_nested_three_block_unordered_nl_block_drop_block_thematics_around_fenced_code_block()
        +test_nested_three_block_unordered_nl_block_drop_block_thematics_around_blanks_around_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_list__li_drop_list_thematics_around_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_list__li_drop_list_thematics_around_blanks_around_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_block_single_line_drop_block_thematics_around_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_block_drop_block_thematics_around_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_block_drop_block_thematics_around_blanks_around_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_block_drop_block_with_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_block_drop_block_with_blanks_around_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_block_with_extra_single_indent_drop_block_with_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_block_with_extra_double_indent_drop_block_with_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_block_with_extra_triple_indent_drop_block_with_fenced_code_block()
        +test_nested_three_block_unordered_block_extra_block_drop_block_extra_block_drop_block_fenced()
        +test_nested_three_block_unordered_block_extra_block_drop_block_extra_block_drop_block_blanks_around_fenced()
        +test_nested_three_block_unordered_nl_block_drop_block_with_fenced()
        +test_nested_three_block_unordered_nl_block_drop_block_with_blanks_around_fenced()
        +test_nested_three_block_unordered_block_thematics_around_text_and_fenced()
        +test_nested_three_block_unordered_block_thematics_around_text_and_blanks_around_fenced()
        +test_nested_three_block_unordered_block_thematic_drop_block_and_list_with_text()
        +test_nested_three_block_unordered_block_thematic_nl_text_drop_block_and_list_with_text()
        +test_nested_three_block_unordered_block_thematic_nl_fenced_with_drop_block_li()
        +test_nested_three_block_unordered_block_fenced_with_drop_right_after()
        +test_nested_three_block_unordered_block_empty_fenced_with_drop_right_after()
        +test_nested_three_block_unordered_block_thematics_around_blanks_around_text_drop_block_li_li_extra_block_drop_block_li()
        +test_nested_three_block_unordered_block_thematics_around_blank_drop_block_li_text()
        +test_nested_three_block_unordered_block_thematics_around_blank_drop_block_li_extra_block_text()
        +test_nested_three_block_unordered_nl_block_drop_block_headings_around_fenced()
        +test_nested_three_block_unordered_nl_block_drop_block_blank_thematics_around_fenced()
        +test_nested_three_block_unordered_extra_block_with_no_space_after_drop_block_thematics_around_fenced()
        +test_nested_three_block_unordered_extra_block_drop_block_thematic_extra_block_drop_block_thematics_around_fenced()
        +test_nested_three_block_unordered_extra_list_drop_list_thematics_around_fenced()
    }

    class TestMarkdownNestedThreeOrderedBlockUnordered {
        +test_nested_three_ordered_block_unordered_nl_extra_block_drop_block_fenced()
        +test_nested_three_ordered_block_unordered_nl_extra_block_drop_block_blanks_around_fenced()
        +test_nested_three_ordered_block_unordered_thematics_around_fenced()
        +test_nested_three_ordered_block_unordered_extra_block_drop_block_with_headings_around_fenced()
        +test_nested_three_ordered_block_unordered_extra_list_li_drop_list_with_fenced()
        +test_nested_three_ordered_block_unordered_extra_list_li_drop_list_with_blanks_around_fenced()
        +test_nested_three_ordered_block_unordered_extra_list_li_drop_list_with_thematics_around_fenced()
        +test_nested_three_ordered_block_unordered_extra_list_li_drop_list_with_thematics_around_blanks_around_fenced()
        +test_nested_three_ordered_block_unordered_li_with_empty_prefix_extra_block_drop_block_headings_around_text()
        +test_nested_three_ordered_block_unordered_extra_block_drop_block_headings_around_text()
        +test_nested_three_ordered_block_unordered_thematics_around_headings_around_text()
        +test_nested_three_ordered_block_unordered_extra_block_drop_block_thematics_around_text()
        +test_nested_three_ordered_block_unordered_extra_block_drop_block_html_around_text()
    }
Loading

File-Level Changes

Change Details Files
Added new test cases for nested block quotes, lists, and fenced code blocks
  • Added tests for various combinations of nested block quotes, unordered lists, and fenced code blocks
  • Added tests for handling thematic breaks and HTML comments within nested structures
  • Added tests for different indentation levels and dropping of list items
test/rules/test_md031.py
test/nested_three/test_markdown_nested_three_block_unordered_block.py
test/nested_three/test_markdown_nested_three_block_unordered_unordered.py
test/nested_three/test_markdown_nested_three_block_block_unordered.py
Modified container block processing logic
  • Updated the __reduce_containers_if_required_bq_list function to handle both block quotes and lists
  • Changed the assertion in __reduce_containers_if_required_bq to count block quote tokens instead of total tokens
pymarkdown/container_blocks/container_helper.py
Updated code coverage metrics
  • Increased branch coverage from 5367 to 5385
  • Increased line coverage from 21037 to 21081
publish/coverage.json

Assessment against linked issues

Issue Objective Addressed Explanation
#1233 Add more tests to cover cases of Nested Containers and multi-level drops
#1233 Ensure proper handling of nested containers and multi-level drops by both the parser and rule Md031
#1234 Fix parsing issues for multiple-drops showing incorrect parsing
#1234 Add new test cases for multiple-drops scenarios
#1235 Fix asserts while scanning multiple drops in containers

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time. You can also use
    this command to specify where the summary should be inserted.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @jackdewinter - I've reviewed your changes and they look great!

Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟢 Security: all looks good
  • 🟡 Testing: 5 issues found
  • 🟢 Complexity: all looks good
  • 🟡 Documentation: 1 issue found

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@@ -352,6 +377,17 @@ def __abcd(
container_token_indices: List[int],
) -> Optional[str]:
prefix = None

if (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider a more general approach for handling edge cases

The new condition added to the __abcd method seems very specific. Consider refactoring this part to handle similar cases more generally, which could improve maintainability and reduce the need for future specific conditions.

        if self._is_edge_case(container_stack, removed_tokens):

Comment on lines +344 to +353
@staticmethod
def __abcd_inner(
removed_tokens: List[MarkdownToken], removed_token_indices: List[int]
) -> bool:
do_check = True
if removed_tokens[0].is_list_start:
current_leading_spaces = cast(
ListStartMarkdownToken, removed_tokens[0]
).leading_spaces
else:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): Evaluate performance impact of method extraction

The extraction of __abcd_inner method improves readability, but ensure it doesn't introduce performance penalties if called frequently. Consider inlining if profiling shows significant overhead.

@@ -184,7 +184,6 @@ def test_api_scan_for_non_markdown_file_with_alternate_extensions():


@pytest.mark.timeout(30)
@pytest.mark.skip
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (testing): Removed skip mark from test_api_scan_recursive_for_directory

The skip mark has been removed from this test. Make sure that the test is now passing and that it doesn't significantly increase the overall test execution time.

Comment on lines +172 to 177
(
pytest.param(i, marks=pytest.mark.skip)
if i.mark_fix_as_skipped or i.mark_scan_as_skipped
else i
)
for i in scanTests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Consider adding a test for the new condition

The condition for skipping tests has been updated to include 'i.mark_scan_as_skipped'. It would be beneficial to add a test case that verifies this new condition.

@pytest.mark.parametrize(
    "test_case",
    [
        (
            pytest.param(i, marks=pytest.mark.skip)
            if i.mark_fix_as_skipped or i.mark_scan_as_skipped
            else i
        )
        for i in scanTests
    ],
)
def test_skip_condition(test_case):
    assert not (test_case.mark_fix_as_skipped or test_case.mark_scan_as_skipped)

@@ -6049,515 +6002,363 @@ def test_extra_043a():


@pytest.mark.gfm
def test_extra_044x():
def test_extra_044d():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Addition of new test case test_extra_044d

This new test case appears to be testing fenced code blocks within nested blockquotes. Ensure it covers all relevant edge cases for this scenario.

def test_extra_044d():
    """
    Test fenced code blocks within nested blockquotes.
    """
    # Arrange
    source_markdown = """> > inner block
> > inner block
> This is text and no blank line.
> ```block
> A code block
> ```
> This is a blank line and some text.
"""
    expected_gfm = """<blockquote>
<blockquote>
<p>inner block
inner block
This is text and no blank line.</p>
</blockquote>
<pre><code class="language-block">A code block
</code></pre>
<p>This is a blank line and some text.</p>
</blockquote>"""

    # Act & Assert
    act_and_assert(source_markdown, expected_gfm, expected_tokens)

</blockquote>"""

# Act & Assert
act_and_assert(source_markdown, expected_gfm, expected_tokens)


@pytest.mark.gfm
def test_extra_044b():
def test_extra_044jeb():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Addition of new test case test_extra_044jeb

This test case involves complex nesting of lists and blockquotes. Ensure that it adequately tests the edge cases for such structures.

        "[end-ulist:::True]",
        "[end-ulist:::True]",
        "[end-block-quote:::True]",
        "[tbreak(4,1):-::-----]",
        "[fcode-block(5,1):`:3:block:::::]",
        "[text(6,1):A code block:]",
        "[end-fcode-block:::3:False]",
        "[tbreak(8,1):-::-----]",
        "[para(9,1):]",
        "[text(9,1):another list:]",

Comment on lines 6164 to 6165
@pytest.mark.skip
def test_extra_044jec():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): New skipped test case test_extra_044jec

This test is marked to be skipped. Consider adding a comment explaining why it's skipped and when it should be unskipped.

@pytest.mark.skip(reason="TBD: Explain why this test is skipped and when it should be unskipped")
def test_extra_044jec():

@@ -15,7 +15,9 @@
<!--- pyml disable-next-line no-duplicate-heading-->
### Changed

- None
- [Issue 1231)](https://github.com/jackdewinter/pymarkdown/issues/1231)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (documentation): Fix typo in issue number link

There's an extra closing parenthesis after the issue number. It should be '[Issue 1231]' instead of '[Issue 1231)]'.

Copy link

codecov bot commented Oct 23, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (3335836) to head (ec34bc6).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #1241   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          191       191           
  Lines        21037     21081   +44     
  Branches      2683      2692    +9     
=========================================
+ Hits         21037     21081   +44     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jackdewinter jackdewinter merged commit 911e871 into main Oct 23, 2024
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant