"""XHTML-MP emission: prolog, head, block mapping, and well-formedness.""" from __future__ import annotations from xml.etree import ElementTree import pytest from wapdown.renderers.xhtmlmp.renderer import XHTML_PROLOG TWO_SECTIONS = "Intro.\n\n{.card One}\nFirst.\n\n{.card Two}\nSecond.\n" def parse(markup: str) -> ElementTree.Element: """Parse the page, proving it is well-formed XML. ElementTree honours the DOCTYPE declaration without trying to fetch the external DTD, so this never depends on a network round trip to wapforum.org. """ return ElementTree.fromstring(markup) class TestDocumentShape: def test_prolog_and_doctype(self, render_xhtmlmp): markup = render_xhtmlmp("Body.\n") assert markup.startswith(XHTML_PROLOG) assert 'PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"' in markup def test_root_element_is_html(self, render_xhtmlmp): # ElementTree namespace-qualifies the tag because of the xhtml xmlns. assert parse(render_xhtmlmp("Body.\n")).tag == "{http://www.w3.org/1999/xhtml}html" def test_output_is_well_formed(self, render_xhtmlmp): parse(render_xhtmlmp(TWO_SECTIONS)) def test_no_carriage_returns(self, render_xhtmlmp): assert "\r" not in render_xhtmlmp(TWO_SECTIONS) def test_card_breaks_do_not_split_the_page(self, render_xhtmlmp): # Cards are a WAP 1.x screen-budget concern; XHTML-MP renders one # continuous page and a {.card} marker draws nothing of its own. markup = render_xhtmlmp(TWO_SECTIONS) assert markup.count("Fish & Chips" in markup class TestBlockMapping: @pytest.mark.parametrize( ("source", "expected"), [ ("Just text.\n", "

Just text.

"), ("> quoted\n", "

quoted

"), ("```\ncode\n```\n", "
code
"), ("---\n", "
"), ], ) def test_blocks(self, render_xhtmlmp, source, expected): assert expected in render_xhtmlmp(source) @pytest.mark.parametrize("level", [1, 2, 3, 4, 5, 6]) def test_headings_use_real_heading_elements(self, render_xhtmlmp, level): markup = render_xhtmlmp(f"{'#' * level} Title\n") assert f"Title" in markup assert "" not in markup # no FIGlet/WML-style banner substitute def test_heading_level_beyond_six_clamps(self, render_xhtmlmp): # Markdown itself caps at h6, but a manually-crafted payload # shouldn't be able to emit an invalid element name. markup = render_xhtmlmp("###### Deep\n") assert "
Deep
" in markup def test_unordered_list(self, render_xhtmlmp): markup = render_xhtmlmp("- a\n- b\n") assert "" in markup def test_ordered_list(self, render_xhtmlmp): markup = render_xhtmlmp("1. a\n2. b\n") assert "
  1. a
  2. b
" in markup def test_nested_list_is_spliced_into_parent_item(self, render_xhtmlmp): markup = render_xhtmlmp("- a\n - nested\n- b\n") # The sub-list must sit *inside* its parent
  • , not after it, or # the result is not a valid nested list. assert "
  • a
    • nested
  • " in markup parsed = parse(f"{markup[markup.index('')]}") outer_items = parsed.find("ul").findall("li") assert len(outer_items) == 2 assert outer_items[0].find("ul/li").text == "nested" def test_blank_line_does_not_split_a_list(self, render_xhtmlmp): # A loose Markdown list (blank line between items) is still one # list, matching the WML renderer's own convention. markup = render_xhtmlmp("- a\n\n- b\n") assert markup.count("