Skip to content

Commit 89d6b8c

Browse files
committed
Add tests
1 parent 7be4f61 commit 89d6b8c

File tree

4 files changed

+26
-8
lines changed

4 files changed

+26
-8
lines changed

src/js/bun.lockb

-784 Bytes
Binary file not shown.

src/reactpy/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from reactpy import config, logging, reactjs, types, web, widgets
2-
from reactpy._html import html
2+
from reactpy._html import h, html
33
from reactpy.core import hooks
44
from reactpy.core.component import component
55
from reactpy.core.events import event
@@ -32,6 +32,7 @@
3232
"config",
3333
"create_context",
3434
"event",
35+
"h",
3536
"hooks",
3637
"html",
3738
"logging",

src/reactpy/utils.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from lxml import etree
1010
from lxml.html import fromstring
1111

12-
from reactpy import html as _html
12+
from reactpy import h
1313
from reactpy.transforms import RequiredTransforms, attributes_to_reactjs
1414
from reactpy.types import Component, VdomDict
1515

@@ -105,11 +105,11 @@ def string_to_reactpy(
105105
event handler that prevents the browser from navigating to the link. This is
106106
useful if you would rather have `reactpy-router` handle your URL navigation.
107107
"""
108-
if not html.strip():
109-
return _html.div()
110108
if not isinstance(html, str):
111109
msg = f"Expected html to be a string, not {type(html).__name__}"
112110
raise TypeError(msg)
111+
if not html.strip():
112+
return h.div()
113113
if "<" not in html or ">" not in html:
114114
msg = "Expected html string to contain HTML tags, but no tags were found."
115115
raise ValueError(msg)
@@ -158,7 +158,7 @@ def _etree_to_vdom(
158158
attributes = attributes_to_reactjs(dict(node.items()))
159159

160160
# Convert the lxml node to a VDOM dict
161-
constructor = getattr(_html, str(node.tag))
161+
constructor = getattr(h, str(node.tag))
162162
el = constructor(attributes, children)
163163

164164
# Perform necessary transformations on the VDOM attributes to meet VDOM spec
@@ -241,13 +241,13 @@ def component_to_vdom(component: Component) -> VdomDict:
241241
"""Convert the first render of a component into a VDOM dictionary"""
242242
result = component.render()
243243

244+
if result is None:
245+
return h.fragment()
244246
if isinstance(result, dict):
245247
return result
246248
if hasattr(result, "render"):
247249
return component_to_vdom(cast(Component, result))
248-
elif isinstance(result, str):
249-
return _html.div(result)
250-
return _html.div()
250+
return h.div(result) if isinstance(result, str) else h.div()
251251

252252

253253
def _react_attribute_to_html(key: str, value: Any) -> tuple[str, str]:

tests/test_utils.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,23 @@ def test_string_to_reactpy(case):
9292
assert utils.string_to_reactpy(case["source"]) == case["model"]
9393

9494

95+
@pytest.mark.parametrize("source", ["", " ", "\n\t "])
96+
def test_string_to_reactpy_empty_source(source):
97+
assert utils.string_to_reactpy(source) == html.div()
98+
99+
100+
@pytest.mark.parametrize("source", [123, None, object()])
101+
def test_string_to_reactpy_non_string_source(source):
102+
with pytest.raises(TypeError):
103+
utils.string_to_reactpy(source) # type: ignore[arg-type]
104+
105+
106+
@pytest.mark.parametrize("source", ["no tags", "plain text", "just words"])
107+
def test_string_to_reactpy_missing_tags(source):
108+
with pytest.raises(ValueError):
109+
utils.string_to_reactpy(source)
110+
111+
95112
@pytest.mark.parametrize(
96113
"case",
97114
[

0 commit comments

Comments
 (0)