"""Unit tests for html_to_sx converter.""" from __future__ import annotations import pytest from shared.sx.html_to_sx import html_to_sx class TestBasicElements: def test_simple_paragraph(self): assert html_to_sx("
Hello
") == '(p "Hello")' def test_with_class(self): assert html_to_sx('Hi
') == '(p :class "intro" "Hi")' def test_multiple_attrs(self): result = html_to_sx('click') assert result == '(a :href "u" :class "link" "click")' def test_nested_inline(self): result = html_to_sx("Hello world
") assert result == '(p "Hello " (em "world"))' def test_deeply_nested(self): result = html_to_sx("bold
')
assert result == '(img :src "a.jpg" :alt "pic")'
def test_hr(self):
assert html_to_sx("A
B
") assert result == '(<> (p "A") (p "B"))' def test_single_top_level(self): result = html_to_sx("Only
") assert result == '(p "Only")' def test_text_only(self): result = html_to_sx("just text") assert result == '"just text"' def test_empty(self): assert html_to_sx("") == '""' def test_whitespace_only(self): assert html_to_sx(" \n ") == '""' class TestWhitespace: def test_root_whitespace_stripped(self): result = html_to_sx("\nA
\nB
\n") assert result == '(<> (p "A") (p "B"))' class TestEntities: def test_amp(self): result = html_to_sx("A & B
") assert result == '(p "A & B")' def test_lt_gt(self): result = html_to_sx("<tag>
") assert result == '(p "hello world
") assert result == '(p "hello\u00a0world")' class TestEscaping: def test_quotes_in_text(self): result = html_to_sx('He said "hello"
') assert result == '(p "He said \\"hello\\"")' def test_backslash_in_text(self): result = html_to_sx("a\\b
") assert result == '(p "a\\\\b")' def test_quotes_in_attr(self): # Attribute values with quotes get escaped result = html_to_sx('hi
") assert result == '(p "hi")' class TestMixedContent: def test_caption_with_link(self): result = html_to_sx('Photo by Author') assert result == '(<> "Photo by " (a :href "https://x.com" "Author"))' def test_caption_plain_text(self): result = html_to_sx("Figure 1") assert result == '"Figure 1"' class TestRoundtrip: """html_to_sx → parse → render should produce equivalent HTML.""" def _roundtrip(self, html_in: str) -> str: from shared.sx.parser import parse from shared.sx.html import render sx_src = html_to_sx(html_in) expr = parse(sx_src) return render(expr) def test_simple(self): assert self._roundtrip("Hello
") == "Hello
" def test_nested(self): assert self._roundtrip("A B C
") == "A B C
" def test_void(self): assert self._roundtrip('
') == '
'
def test_link(self):
html = 'click'
assert self._roundtrip(html) == html
def test_entities_roundtrip(self):
# Entities get decoded by parser, then re-escaped by render
assert self._roundtrip("A & B
") == "A & B
" def test_multi_block(self): html = "A
B
" assert self._roundtrip(html) == html