from dataclasses import dataclass from typing import Any import pytest from fasthtml.components import Button from myutils.observable import make_observable, bind from myfasthtml.core.commands import Command, CommandsManager from myfasthtml.core.constants import ROUTE_ROOT, Routes from myfasthtml.test.matcher import matches @dataclass class Data: value: Any def callback(): return "Hello World" @pytest.fixture(autouse=True) def reset_command_manager(): CommandsManager.reset() def test_i_can_create_a_command_with_no_params(): command = Command('test', 'Command description', callback) assert command.id is not None assert command.name == 'test' assert command.description == 'Command description' assert command.execute() == "Hello World" def test_command_are_registered(): command = Command('test', 'Command description', callback) assert CommandsManager.commands.get(str(command.id)) is command def test_i_can_bind_a_command_to_an_element(): command = Command('test', 'Command description', callback) elt = Button() updated = command.bind_ft(elt) expected = Button(hx_post=f"{ROUTE_ROOT}{Routes.Commands}") assert matches(updated, expected) def test_i_can_suppress_swapping_with_target_attr(): command = Command('test', 'Command description', callback).htmx(target=None) elt = Button() updated = command.bind_ft(elt) expected = Button(hx_post=f"{ROUTE_ROOT}{Routes.Commands}", hx_swap="none") assert matches(updated, expected) def test_i_can_bind_a_command_to_an_observable(): data = Data("hello") def on_data_change(old, new): return old, new def another_callback(): data.value = "new value" return "another callback result" make_observable(data) bind(data, "value", on_data_change) command = Command('test', 'Command description', another_callback).bind(data) res = command.execute() assert res == ["another callback result", ("hello", "new value")] def test_i_can_bind_a_command_to_an_observable_2(): data = Data("hello") def on_data_change(old, new): return old, new def another_callback(): data.value = "new value" return ["another 1", "another 2"] make_observable(data) bind(data, "value", on_data_change) command = Command('test', 'Command description', another_callback).bind(data) res = command.execute() assert res == ["another 1", "another 2", ("hello", "new value")]