Coverage for tests / test_widget_rendering.py: 99%
68 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-03 15:41 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-03 15:41 +0000
1import sys
3import types
4import json
5import pytest
7from tadkit.utils.ui import sanitize_default, WidgetFactory
10# =====================================================
11# 1. Tests for sanitize_default
12# =====================================================
13@pytest.mark.parametrize(
14 "default,min_val,max_val,ptype,closed,expected",
15 [
16 (5, 0, 10, int, "both", 5), # within range
17 (-5, 0, 10, int, "both", 0), # below min -> clamp
18 (15, 0, 10, int, "both", 10), # above max -> clamp
19 (0, 0, 10, int, "right", 1), # closed=right shifts up
20 (10, 0, 10, int, "left", 9), # closed=left shifts down
21 (None, 0, 10, int, "both", 0), # None -> default to 0
22 (0.5, 0.0, 1.0, float, "both", 0.5), # float ok
23 (-0.5, 0.0, 1.0, float, "both", 0.0), # clamp float min
24 (1.5, 0.0, 1.0, float, "both", 1.0), # clamp float max
25 ],
26)
27def test_sanitize_default(default, min_val, max_val, ptype, closed, expected):
28 result = sanitize_default(default, min_val, max_val, ptype, closed)
29 assert (
30 abs(result - expected) < 1e-10
31 if isinstance(result, float)
32 else result == expected
33 )
36def test_sanitize_default_allow_none():
37 assert sanitize_default(None, 0, 10, int, allow_none=True) is None
40# =====================================================
41# 2. Tests for WidgetFactory (no_ui)
42# =====================================================
43@pytest.fixture
44def wf_no_ui():
45 return WidgetFactory(frontend="no_ui")
48def test_make_numeric_no_ui(wf_no_ui):
49 widget = wf_no_ui.make_numeric("Age", 25, 0, 100, int, "Age in years")
50 assert widget["type"] == "number"
51 assert widget["default"] == 25
52 assert widget["min"] == 0
53 assert widget["max"] == 100
56def test_make_dropdown_no_ui(wf_no_ui):
57 widget = wf_no_ui.make_dropdown("Color", ["red", "blue"], "blue", "Pick a color")
58 assert widget["type"] == "dropdown"
59 assert "blue" in widget["options"]
62def test_make_text_no_ui(wf_no_ui):
63 widget = wf_no_ui.make_text("Name", "Alice", "User name")
64 assert widget["type"] == "text"
65 assert widget["default"] == "Alice"
68def test_make_dict_no_ui(wf_no_ui):
69 d = {"a": 1}
70 widget = wf_no_ui.make_dict("Config", d, "Settings dict")
71 assert widget["type"] == "dict"
72 assert widget["default"] == d
75# =====================================================
76# 3. Tests for WidgetFactory (ipywidgets mocked)
77# =====================================================
78@pytest.fixture
79def wf_ipywidgets(monkeypatch):
80 # Mock ipywidgets
81 class DummyWidget:
82 def __init__(self, **kwargs):
83 self.kwargs = kwargs
85 class DummyLayout:
86 def __init__(self, **kwargs):
87 self.kwargs = kwargs
89 mock_widgets = types.SimpleNamespace(
90 BoundedIntText=DummyWidget,
91 BoundedFloatText=DummyWidget,
92 Dropdown=DummyWidget,
93 Text=DummyWidget,
94 Textarea=DummyWidget,
95 Layout=DummyLayout,
96 )
97 monkeypatch.setitem(sys.modules, "ipywidgets", mock_widgets)
98 return WidgetFactory(frontend="ipywidgets")
101def test_make_numeric_ipywidgets(wf_ipywidgets):
102 widget = wf_ipywidgets.make_numeric("Num", 5, 0, 10, int, "desc")
103 assert hasattr(widget, "kwargs")
104 assert widget.kwargs["value"] == 5
107def test_make_dropdown_ipywidgets(wf_ipywidgets):
108 widget = wf_ipywidgets.make_dropdown("Choice", ["a", "b"], "a", "desc")
109 assert "value" in widget.kwargs
110 assert widget.kwargs["value"] == "a"
113# =====================================================
114# 4. Tests for WidgetFactory (Streamlit mocked)
115# =====================================================
116@pytest.fixture
117def wf_streamlit(monkeypatch):
118 mock_st = types.SimpleNamespace(
119 number_input=lambda **kw: kw,
120 selectbox=lambda *a, **kw: kw,
121 text_input=lambda *a, **kw: kw,
122 text_area=lambda *a, **kw: kw,
123 )
124 monkeypatch.setitem(sys.modules, "streamlit", mock_st)
125 return WidgetFactory(frontend="st")
128def test_make_numeric_streamlit(wf_streamlit):
129 widget = wf_streamlit.make_numeric("Num", 5, 0, 10, int, "desc")
130 assert "value" in widget
131 assert widget["value"] == 5
134def test_make_text_streamlit(wf_streamlit):
135 widget = wf_streamlit.make_text("Name", "Bob", "desc")
136 assert widget["value"] == "Bob"
139def test_make_dict_streamlit(wf_streamlit):
140 widget = wf_streamlit.make_dict("Config", {"x": 1}, "desc")
141 assert "value" in widget
142 json.loads(widget["value"]) # should be valid JSON