112 lines
3.0 KiB
Python
112 lines
3.0 KiB
Python
"""Tests for AST parser that converts Python components to IR."""
|
|
|
|
import textwrap
|
|
|
|
|
|
def test_parse_hello_world_component():
|
|
"""Test parsing the simplest possible component - static p tag with text."""
|
|
from ritz.parser import parse_component
|
|
|
|
source = textwrap.dedent(
|
|
"""
|
|
@component
|
|
def HelloWorld():
|
|
with P():
|
|
yield "Hello World"
|
|
"""
|
|
)
|
|
|
|
ir = parse_component(source)
|
|
|
|
# Verify component structure
|
|
assert ir["type"] == "component"
|
|
assert ir["name"] == "HelloWorld"
|
|
assert ir["params"] == []
|
|
|
|
# Verify body contains a with statement
|
|
assert len(ir["body"]) == 1
|
|
with_stmt = ir["body"][0]
|
|
assert with_stmt["type"] == "with"
|
|
assert with_stmt["element"]["tag"] == "P"
|
|
assert with_stmt["element"]["props"] == {}
|
|
|
|
# Verify yield inside with
|
|
assert len(with_stmt["body"]) == 1
|
|
yield_stmt = with_stmt["body"][0]
|
|
assert yield_stmt["type"] == "yield"
|
|
assert yield_stmt["value"]["type"] == "constant"
|
|
assert yield_stmt["value"]["value"] == "Hello World"
|
|
|
|
|
|
def test_parse_component_with_props():
|
|
"""Test parsing element with props (class, id, etc)."""
|
|
from ritz.parser import parse_component
|
|
|
|
source = textwrap.dedent(
|
|
"""
|
|
@component
|
|
def StyledDiv():
|
|
with Div(class_="container", id="main"):
|
|
yield "Content"
|
|
"""
|
|
)
|
|
|
|
ir = parse_component(source)
|
|
with_stmt = ir["body"][0]
|
|
|
|
assert with_stmt["element"]["tag"] == "Div"
|
|
# Props are transformed to IR nodes
|
|
assert with_stmt["element"]["props"]["class_"] == {"type": "constant", "value": "container"}
|
|
assert with_stmt["element"]["props"]["id"] == {"type": "constant", "value": "main"}
|
|
|
|
|
|
def test_parse_nested_elements():
|
|
"""Test parsing nested with statements."""
|
|
from ritz.parser import parse_component
|
|
|
|
source = textwrap.dedent(
|
|
"""
|
|
@component
|
|
def Nested():
|
|
with Div():
|
|
with P():
|
|
yield "Inner text"
|
|
"""
|
|
)
|
|
|
|
ir = parse_component(source)
|
|
outer_with = ir["body"][0]
|
|
assert outer_with["element"]["tag"] == "Div"
|
|
|
|
inner_with = outer_with["body"][0]
|
|
assert inner_with["type"] == "with"
|
|
assert inner_with["element"]["tag"] == "P"
|
|
|
|
yield_stmt = inner_with["body"][0]
|
|
assert yield_stmt["value"]["value"] == "Inner text"
|
|
|
|
|
|
def test_parse_multiple_yields():
|
|
"""Test parsing multiple yield statements in sequence."""
|
|
from ritz.parser import parse_component
|
|
|
|
source = textwrap.dedent(
|
|
"""
|
|
@component
|
|
def Multiple():
|
|
with Div():
|
|
yield "First"
|
|
yield "Second"
|
|
yield "Third"
|
|
"""
|
|
)
|
|
|
|
ir = parse_component(source)
|
|
with_stmt = ir["body"][0]
|
|
|
|
assert len(with_stmt["body"]) == 3
|
|
assert all(stmt["type"] == "yield" for stmt in with_stmt["body"])
|
|
assert with_stmt["body"][0]["value"]["value"] == "First"
|
|
assert with_stmt["body"][1]["value"]["value"] == "Second"
|
|
assert with_stmt["body"][2]["value"]["value"] == "Third"
|