"""Document topology: sectioning, byte packing, and navigation wiring.""" from __future__ import annotations import re import pytest from wapdown.renderers.wml.deck import greedy_pack, slugify TWO_SECTIONS = """\ Intro text. {.card Weather} Cold and clear. {.card Status} North Loop open. """ THREE_HEADINGS = """\ # Title Intro text. ## Alpha First section. ## Beta Second section. ## Gamma Third section. """ def card_ids(markup: str) -> list[str]: return re.findall(r' dict[str, str]: """Map each card id to that card's markup.""" chunks = re.split(r"(?=")[0] return out class TestSectioning: def test_plain_document_stays_one_card(self, render): markup = render("# Title\n\nJust a paragraph.\n") assert card_ids(markup) == ["card1"] def test_headings_alone_do_not_split(self, render): # Splitting is opt-in: a document full of headings is still one card # until split_level says otherwise. assert card_ids(render(THREE_HEADINGS)) == ["card1"] def test_split_level_splits_at_that_heading(self, render): markup = render(THREE_HEADINGS, split_level=2) assert card_ids(markup) == ["menu", "card1", "card2", "card3"] def test_split_level_that_matches_nothing_stays_one_card(self, render): assert card_ids(render(THREE_HEADINGS, split_level=5)) == ["card1"] def test_card_markers_split(self, render): assert card_ids(render(TWO_SECTIONS)) == ["menu", "card1", "card2"] def test_card_markers_win_over_split_level(self, render): # An explicit boundary in the document is a stronger statement of # intent than a structural rule passed on the command line. markup = render( "Intro.\n\n{.card One}\n## Heading\n\nBody.\n\n{.card Two}\nMore.\n", split_level=2, ) assert card_ids(markup) == ["menu", "card1", "card2"] def test_marker_title_is_used(self, render): assert '' in render(TWO_SECTIONS) def test_untitled_marker_falls_back_to_first_heading(self, render): markup = render("Intro.\n\n{.card}\n## Weather\n\nCold.\n\n{.card Two}\nx\n") assert '' in markup def test_marker_without_any_heading_is_untitled(self, render): markup = render("Intro.\n\n{.card}\nCold.\n\n{.card Two}\nx\n") assert '' in markup def test_preamble_lands_on_the_menu_card(self, render): assert "Intro text." in cards(render(TWO_SECTIONS))["menu"] class TestHubAndSpoke: def test_menu_links_to_every_section(self, render): menu = cards(render(TWO_SECTIONS))["menu"] assert 'Weather' in menu assert 'Status' in menu def test_select_style_menu(self, render): menu = cards(render(TWO_SECTIONS, menu_style="select"))["menu"] assert '