I can bind elements
This commit is contained in:
0
tests/core/__init__.py
Normal file
0
tests/core/__init__.py
Normal file
96
tests/core/test_bindings.py
Normal file
96
tests/core/test_bindings.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
import pytest
|
||||
from fasthtml.components import Label, Input
|
||||
from myutils.observable import collect_return_values
|
||||
|
||||
from myfasthtml.core.bindings import BindingsManager, Binding
|
||||
|
||||
|
||||
@dataclass
|
||||
class Data:
|
||||
value: str = "Hello World"
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def reset_binding_manager():
|
||||
BindingsManager.reset()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def data():
|
||||
return Data()
|
||||
|
||||
|
||||
def test_i_can_register_a_binding(data):
|
||||
binding = Binding(data, "value")
|
||||
|
||||
assert binding.id is not None
|
||||
assert binding.data is data
|
||||
assert binding.data_attr == 'value'
|
||||
|
||||
|
||||
def test_i_can_register_a_binding_with_default_attr(data):
|
||||
binding = Binding(data)
|
||||
|
||||
assert binding.id is not None
|
||||
assert binding.data is data
|
||||
assert binding.data_attr == 'value'
|
||||
|
||||
|
||||
def test_i_can_retrieve_a_registered_binding(data):
|
||||
binding = Binding(data)
|
||||
assert BindingsManager.get_binding(binding.id) is binding
|
||||
|
||||
|
||||
def test_i_can_reset_bindings(data):
|
||||
Binding(data)
|
||||
assert len(BindingsManager.bindings) != 0
|
||||
|
||||
BindingsManager.reset()
|
||||
assert len(BindingsManager.bindings) == 0
|
||||
|
||||
|
||||
def test_i_can_bind_an_element_to_a_binding(data):
|
||||
elt = Label("hello", id="label_id")
|
||||
Binding(data, ft=elt)
|
||||
|
||||
data.value = "new value"
|
||||
|
||||
assert elt.children[0] == "new value"
|
||||
assert elt.attrs["hx-swap-oob"] == "true"
|
||||
assert elt.attrs["id"] == "label_id"
|
||||
|
||||
|
||||
def test_i_can_bind_an_element_attr_to_a_binding(data):
|
||||
elt = Input(value="somme value", id="input_id")
|
||||
|
||||
Binding(data, ft=elt, ft_attr="value")
|
||||
|
||||
data.value = "new value"
|
||||
|
||||
assert elt.attrs["value"] == "new value"
|
||||
assert elt.attrs["hx-swap-oob"] == "true"
|
||||
assert elt.attrs["id"] == "input_id"
|
||||
|
||||
|
||||
def test_bound_element_has_an_id():
|
||||
elt = Label("hello")
|
||||
assert elt.attrs.get("id", None) is None
|
||||
|
||||
Binding(Data(), ft=elt)
|
||||
assert elt.attrs.get("id", None) is not None
|
||||
|
||||
|
||||
def test_i_can_collect_updates_values(data):
|
||||
elt = Label("hello")
|
||||
Binding(data, ft=elt)
|
||||
|
||||
data.value = "new value"
|
||||
collected = collect_return_values(data)
|
||||
assert collected == [elt]
|
||||
|
||||
# a second time to ensure no side effect
|
||||
data.value = "another value"
|
||||
collected = collect_return_values(data)
|
||||
assert collected == [elt]
|
||||
@@ -8,7 +8,7 @@ def callback():
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def test_reset_command_manager():
|
||||
def reset_command_manager():
|
||||
CommandsManager.reset()
|
||||
|
||||
|
||||
79
tests/test_integration.py
Normal file
79
tests/test_integration.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
import pytest
|
||||
from fasthtml.components import Input, Label
|
||||
from fasthtml.fastapp import fast_app
|
||||
|
||||
from myfasthtml.controls.helpers import mk
|
||||
from myfasthtml.core.bindings import Binding
|
||||
from myfasthtml.core.commands import Command, CommandsManager
|
||||
from myfasthtml.test.testclient import MyTestClient, TestableElement
|
||||
|
||||
|
||||
def new_value(value):
|
||||
return value
|
||||
|
||||
|
||||
@dataclass
|
||||
class Data:
|
||||
value: str
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def user():
|
||||
test_app, rt = fast_app(default_hdrs=False)
|
||||
user = MyTestClient(test_app)
|
||||
return user
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def rt(user):
|
||||
return user.app.route
|
||||
|
||||
|
||||
class TestingCommand:
|
||||
def test_i_can_trigger_a_command(self, user):
|
||||
command = Command('test', 'TestingCommand', new_value, "this is my new value")
|
||||
testable = TestableElement(user, mk.button('button', command))
|
||||
testable.click()
|
||||
assert user.get_content() == "this is my new value"
|
||||
|
||||
def test_error_is_raised_when_command_is_not_found(self, user):
|
||||
command = Command('test', 'TestingCommand', new_value, "this is my new value")
|
||||
CommandsManager.reset()
|
||||
testable = TestableElement(user, mk.button('button', command))
|
||||
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
testable.click()
|
||||
|
||||
assert "not found." in str(exc_info.value)
|
||||
|
||||
def test_i_can_play_a_complex_scenario(self, user, rt):
|
||||
command = Command('test', 'TestingCommand', new_value, "this is my new value")
|
||||
|
||||
@rt('/')
|
||||
def get(): return mk.button('button', command)
|
||||
|
||||
user.open("/")
|
||||
user.should_see("button")
|
||||
|
||||
user.find_element("button").click()
|
||||
user.should_see("this is my new value")
|
||||
|
||||
|
||||
class TestingBindings:
|
||||
def test_i_can_bind_elements(self, user, rt):
|
||||
@rt("/")
|
||||
def index():
|
||||
data = Data("hello world")
|
||||
input_elt = Input(name="input_name")
|
||||
label_elt = Label()
|
||||
mk.manage_binding(input_elt, Binding(data, ft_attr="value"))
|
||||
mk.manage_binding(label_elt, Binding(data))
|
||||
return input_elt, label_elt
|
||||
|
||||
user.open("/")
|
||||
user.should_see("")
|
||||
testable_input = user.find_element("input")
|
||||
testable_input.send("new value")
|
||||
user.should_see("new value") # the one from the label
|
||||
@@ -1,53 +0,0 @@
|
||||
import pytest
|
||||
from fasthtml.fastapp import fast_app
|
||||
|
||||
from myfasthtml.controls.helpers import mk
|
||||
from myfasthtml.core.commands import Command, CommandsManager
|
||||
from myfasthtml.test.testclient import MyTestClient, TestableElement
|
||||
|
||||
|
||||
def new_value(value):
|
||||
return value
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def user():
|
||||
test_app, rt = fast_app(default_hdrs=False)
|
||||
user = MyTestClient(test_app)
|
||||
return user
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def rt(user):
|
||||
return user.app.route
|
||||
|
||||
|
||||
def test_i_can_trigger_a_command(user):
|
||||
command = Command('test', 'TestingCommand', new_value, "this is my new value")
|
||||
testable = TestableElement(user, mk.button('button', command))
|
||||
testable.click()
|
||||
assert user.get_content() == "this is my new value"
|
||||
|
||||
|
||||
def test_error_is_raised_when_command_is_not_found(user):
|
||||
command = Command('test', 'TestingCommand', new_value, "this is my new value")
|
||||
CommandsManager.reset()
|
||||
testable = TestableElement(user, mk.button('button', command))
|
||||
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
testable.click()
|
||||
|
||||
assert "not found." in str(exc_info.value)
|
||||
|
||||
|
||||
def test_i_can_play_a_complex_scenario(user, rt):
|
||||
command = Command('test', 'TestingCommand', new_value, "this is my new value")
|
||||
|
||||
@rt('/')
|
||||
def get(): return mk.button('button', command)
|
||||
|
||||
user.open("/")
|
||||
user.should_see("button")
|
||||
|
||||
user.find_element("button").click()
|
||||
user.should_see("this is my new value")
|
||||
Reference in New Issue
Block a user