mirror of
https://github.com/divkit/divkit.git
synced 2026-05-07 20:02:32 +00:00
2987d93ba7
commit_hash:cf5070a543788fa57136adb1a4a7ea42f4490329
112 lines
3.7 KiB
Python
112 lines
3.7 KiB
Python
import pytest
|
|
|
|
from pydivkit.core import BaseEntity, Expr, Field, Ref
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Expr (public class)
|
|
# ---------------------------------------------------------------------------
|
|
class TestExpr:
|
|
def test_valid_expr(self):
|
|
e = Expr("@{a + b}")
|
|
assert str(e) == "@{a + b}"
|
|
|
|
def test_repr(self):
|
|
e = Expr("@{some_var}")
|
|
assert repr(e) == "Expr(@{some_var})"
|
|
|
|
def test_str(self):
|
|
e = Expr("@{some_var}")
|
|
assert str(e) == "@{some_var}"
|
|
|
|
def test_invalid_expr_no_closing(self):
|
|
with pytest.raises(ValueError):
|
|
Expr("@{unclosed")
|
|
|
|
def test_invalid_expr_no_at(self):
|
|
with pytest.raises(ValueError):
|
|
Expr("{no_at}")
|
|
|
|
def test_invalid_expr_no_markers(self):
|
|
with pytest.raises(ValueError):
|
|
Expr("notcontains")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Field (public factory function)
|
|
# ---------------------------------------------------------------------------
|
|
class TestField:
|
|
def test_field_creates_entity_field(self):
|
|
"""Field() can be used as a class annotation to define entity fields."""
|
|
|
|
class FieldEntity(BaseEntity):
|
|
name: str = Field()
|
|
|
|
entity = FieldEntity(name="test")
|
|
assert entity.dict() == {"name": "test"}
|
|
|
|
def test_field_with_default(self):
|
|
class DefaultEntity(BaseEntity):
|
|
color: str = Field(default="red")
|
|
|
|
entity = DefaultEntity()
|
|
assert entity.dict() == {"color": "red"}
|
|
|
|
def test_field_with_name_override(self):
|
|
"""Field(name=...) overrides the serialized field name."""
|
|
|
|
class NamedEntity(BaseEntity):
|
|
my_field: str = Field(name="custom_name")
|
|
|
|
entity = NamedEntity(my_field="value")
|
|
assert entity.dict() == {"custom_name": "value"}
|
|
|
|
def test_field_constraints_reflected_in_schema(self):
|
|
"""Field constraints appear in schema output."""
|
|
from pydivkit.core import BaseDiv
|
|
|
|
class ConstraintBase(BaseDiv):
|
|
type: str = Field(name="type", default="constraint_test")
|
|
count: int = Field(ge=0, le=100)
|
|
|
|
class ConstraintChild(ConstraintBase):
|
|
pass
|
|
|
|
schema = ConstraintChild.schema()
|
|
props = schema.get("properties", {})
|
|
assert "count" in props
|
|
count_schema = props["count"]
|
|
assert count_schema.get("minimum") == 0
|
|
assert count_schema.get("maximum") == 100
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Ref (public factory function)
|
|
# ---------------------------------------------------------------------------
|
|
class TestRef:
|
|
def test_ref_non_field_raises(self):
|
|
with pytest.raises(ValueError, match="Expected type is Field"):
|
|
Ref("not_a_field")
|
|
|
|
def test_ref_int_raises(self):
|
|
with pytest.raises(ValueError, match="Expected type is Field"):
|
|
Ref(42)
|
|
|
|
def test_ref_creates_template_reference(self):
|
|
"""Ref() creates a template reference observable in make_div."""
|
|
from pydivkit import DivContainer, DivText, make_div
|
|
|
|
class RefTemplate(DivContainer):
|
|
label: str = Field()
|
|
items = [DivText(text=Ref(label))]
|
|
|
|
result = make_div(RefTemplate(items=[], label="hello"))
|
|
tpl_name = RefTemplate.template_name
|
|
templates = result["templates"]
|
|
assert tpl_name in templates
|
|
# The $text ref is inside the nested DivText item
|
|
tpl_items = templates[tpl_name]["items"]
|
|
text_item = tpl_items[0]
|
|
assert "$text" in text_item
|
|
assert text_item["$text"] == "label"
|