I can bind select

This commit is contained in:
2025-11-08 19:58:47 +01:00
parent 6a05a84f0c
commit ad2823042c
22 changed files with 591 additions and 651 deletions

View File

@@ -24,7 +24,8 @@ from fasthtml.fastapp import fast_app
from myfasthtml.controls.helpers import mk
from myfasthtml.core.bindings import Binding, BooleanConverter
from myfasthtml.test.matcher import matches, AttributeForbidden
from myfasthtml.core.constants import Routes, ROUTE_ROOT
from myfasthtml.test.matcher import matches, AttributeForbidden, AnyValue
from myfasthtml.test.testclient import MyTestClient
@@ -67,7 +68,19 @@ def rt(user):
class TestBindingTextarea:
"""Tests for binding Textarea components."""
def test_i_can_bind_textarea(self, user, rt):
def test_i_can_bind_textarea(self):
data = Data("")
check_box = Textarea(name="textarea_name")
binding = Binding(data)
mk.manage_binding(check_box, binding)
# update the content
res = binding.update({"textarea_name": "Hello world !"})
expected = [Textarea("Hello world !", name="textarea_name", hx_swap_oob="true")]
assert matches(res, expected)
def test_i_can_bind_textarea_with_label(self, user, rt):
"""
Textarea should bind bidirectionally with data.
Value changes should update the label.
@@ -89,27 +102,6 @@ class TestBindingTextarea:
testable_textarea.send("New multiline\ntext content")
user.should_see("New multiline\ntext content")
def test_i_can_bind_textarea_with_empty_initial_value(self, user, rt):
"""
Textarea with empty initial value should update correctly.
"""
@rt("/")
def index():
data = Data("")
textarea_elt = Textarea(name="textarea_name")
label_elt = Label()
mk.manage_binding(textarea_elt, Binding(data))
mk.manage_binding(label_elt, Binding(data))
return textarea_elt, label_elt
user.open("/")
user.should_see("") # Empty initially
testable_textarea = user.find_element("textarea")
testable_textarea.send("First content")
user.should_see("First content")
def test_textarea_append_works_with_binding(self, user, rt):
"""
Appending text to textarea should trigger binding update.
@@ -156,6 +148,80 @@ class TestBindingTextarea:
class TestBindingSelect:
"""Tests for binding Select components (single selection)."""
def test_i_can_bind_select(self):
data = Data("")
select_elt = Select(
Option("Option 1", value="option1"),
Option("Option 2", value="option2"),
Option("Option 3", value="option3"),
name="select_name"
)
binding = Binding(data)
updated = mk.manage_binding(select_elt, binding)
expected = Select(
AttributeForbidden("hx_swap_oob"),
Option("Option 1", value="option1"),
Option("Option 2", value="option2"),
Option("Option 3", value="option3"),
name="select_name",
id=AnyValue(),
hx_post=f"{ROUTE_ROOT}{Routes.Bindings}",
)
assert matches(updated, expected)
def test_i_can_update_select(self):
data = Data("")
select_elt = Select(
Option("Option 1", value="option1"),
Option("Option 2", value="option2"),
Option("Option 3", value="option3"),
name="select_name"
)
binding = Binding(data)
mk.manage_binding(select_elt, binding)
res = binding.update({"select_name": "option2"})
expected = Select(
Option("Option 1", value="option1"),
Option("Option 2", value="option2", selected="true"),
Option("Option 3", value="option3"),
name="select_name",
id=AnyValue(),
hx_post=f"{ROUTE_ROOT}{Routes.Bindings}",
hx_swap_oob="true"
)
assert matches(res, [expected])
def test_i_can_change_selection(self):
data = Data("")
select_elt = Select(
Option("Option 1", value="option1"),
Option("Option 2", value="option2"),
Option("Option 3", value="option3"),
name="select_name"
)
binding = Binding(data)
mk.manage_binding(select_elt, binding)
binding.update({"select_name": "option2"})
res = binding.update({"select_name": "option1"})
expected = Select(
Option("Option 1", value="option1", selected="true"),
Option(AttributeForbidden("selected"), "Option 2", value="option2"),
Option(AttributeForbidden("selected"), "Option 3", value="option3"),
name="select_name",
id=AnyValue(),
hx_post=f"{ROUTE_ROOT}{Routes.Bindings}",
hx_swap_oob="true"
)
assert matches(res, [expected])
def test_i_can_bind_select_single(self, user, rt):
"""
Single select should bind with data.