Skip to content

Expand Markpub parser test coverage for untested block handlers #30

@kraftbj

Description

@kraftbj

Summary

Follow-up to #9. The initial Markpub parser PR added behavioral tests for the top-level structure and several block handlers (paragraph, heading, code, image, separator, filter, classic content, empty/null return) but left a number of block-handler branches untested. This issue tracks filling those gaps before we rely on the parser more heavily.

Background

During review of #9, the test-coverage pass flagged several branches where a regression would ship silently because the existing assertions (assertStringContainsString) would still pass. The PR addressed the highest-impact correctness bugs; this issue addresses the remaining coverage.

Test Plan

Tests live in tests/phpunit/tests/content-parser/class-test-markpub.php.

Priority 1 — untested block handlers (high risk of silent regression)

  • listing() — ordered list
    • Input: <!-- wp:list {"ordered":true} --> with 3 core/list-item inner blocks.
    • Assert exact output: "1. First\n2. Second\n3. Third" (use assertSame on the markdown).
  • listing() — unordered list
    • Same shape without ordered. Assert "- First\n- Second\n- Third".
  • listing() — skips empty items but keeps counter correct
    • Input: 3 items where item 2 has only whitespace.
    • Assert ordered output is "1. First\n2. Third" (counter must not gap to 3.).
  • listing() — inline formatting preserved inside items
    • Input: item with <strong>bold</strong>. Assert "- **bold**" appears.
  • quote()innerBlocks branch
    • Input: core/quote wrapping a core/paragraph. Assert "> Paragraph text".
  • quote() — multi-line prefixing
    • Input: core/quote wrapping two inner paragraphs. Assert each line carries "> " prefix.
  • quote()innerHTML fallback branch
    • Input: core/quote with no innerBlocks, just innerHTML. Assert quote-prefixed markdown.
  • container()core/group, core/columns, core/column
    • One test per block name wrapping a paragraph. Assert inner markdown bubbles up correctly with a \n\n separator.
  • fallback() — delegates to container() when innerBlocks present
    • Synthetic unknown block name with inner paragraph. Assert inner markdown emitted.

Priority 2 — untested branches inside covered handlers

  • image() — returns null when no <img> tag found
    • Input: figure markup with only a figcaption. Assert parse() returns null (or block is absent from output).
  • heading() — default level when attrs.level missing
    • Input: <!-- wp:heading --> with no attrs. Assert leading "## ".
  • heading() — returns null for whitespace-only content
    • Input: heading with only <br> or whitespace. Assert parse returns null (or heading omitted).
  • paragraph() — returns null for whitespace-only content (mirror of heading test).
  • code() — language attribute emitted in fence
    • Input: <!-- wp:code {"language":"php"} -->. Assert output starts with ```php\n.
  • code() — HTML-entity decoding
    • Input code block containing &lt;div&gt;. Assert decoded form appears in fence.
  • Link URL parens escape
    • Input: <a href="https://en.wikipedia.org/wiki/Foo_(bar)">text</a>.
    • Assert URL contains %28bar%29, not raw (bar).
  • <br> hard break conversion
    • Input: paragraph with line1<br>line2. Assert output contains "line1 \nline2" (two spaces + newline).
  • HTML entity decoding in inline text
    • Input: paragraph with &amp;, &#8217;. Assert decoded forms appear.
  • Inline image inside paragraph
    • Input: paragraph containing <img src="x.jpg" alt="x">. Assert ![x](x.jpg) in output (distinct from core/image block path).
  • Nested inline formatting
    • Input: <strong>bold <em>italic</em></strong>. Assert **bold *italic***.

Priority 3 — assertion-strength upgrades

  • Convert existing assertStringContainsString assertions to assertSame on exact markdown output where the format is contract (separator block, fenced code, heading line). This catches block-ordering and whitespace regressions that currently slip through.
  • test_html_to_markdown_filter — verify the filter callback receives $content as the second argument (document the two-arg contract).

Out of Scope

  • Adding a core/table handler ('table' extension was dropped in Add Markpub content parser #9; re-introduce alongside handler).
  • Link target/title attribute support.
  • Support for classic-content block-level HTML (<h1>, <ul>, etc.). inline_html_to_markdown() only handles inline markup today.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions