Skip to content

Commit ea00df7

Browse files
committed
Add tests for new form options
1 parent 982b1fb commit ea00df7

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

tests/test_renderer.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,37 @@ def test_wrapper_options(
118118
'/html/body/div[@class="mb-3"]/div[@class="offset-3" and @attr="MOCK_ATTR"]/'
119119
'input[@name="submit"]'
120120
)
121+
122+
123+
def test_form_options(
124+
renderer_context: RendererContext,
125+
form: MockForm,
126+
parse_html: typing.Callable[[str], etree._ElementTree],
127+
):
128+
html = renderer_context.form(
129+
method="MOCK_METHOD",
130+
action="MOCK_ACTION",
131+
enctype="MOCK_ENCTYPE",
132+
form_class="MOCK_CLASS",
133+
form_attrs=dict(mock_attr="MOCK_VALUE"),
134+
).render(form)
135+
tree = parse_html(html)
136+
# Notice: lxml parser will add html and body automatically in the tree
137+
form = tree.xpath("/html/body/form")[0]
138+
assert form.attrib["method"] == "MOCK_METHOD"
139+
assert form.attrib["action"] == "MOCK_ACTION"
140+
assert form.attrib["enctype"] == "MOCK_ENCTYPE"
141+
assert form.attrib["class"] == "MOCK_CLASS"
142+
assert form.attrib["mock_attr"] == "MOCK_VALUE"
143+
144+
145+
def test_form_options_disable(
146+
renderer_context: RendererContext,
147+
form: MockForm,
148+
parse_html: typing.Callable[[str], etree._ElementTree],
149+
):
150+
html = renderer_context.form(form_enabled=False).render(form)
151+
tree = parse_html(html)
152+
# Notice: lxml parser will add html and body automatically in the tree
153+
assert not tree.xpath("/html/body/form")
154+
assert tree.xpath('/html/body/div/input[@name="email"]')

wtforms_bootstrap5/context.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,16 @@ def __init__(
116116

117117
def form(self, **kwargs) -> RendererContext:
118118
old_options = dataclasses.asdict(self.form_options)
119-
self.form_options = FormOptions(old_options | kwargs)
119+
self.form_options = FormOptions(**(old_options | kwargs))
120+
return self
120121

121122
def field(self, *names: str, **kwargs: str) -> RendererContext:
122123
for name in names:
123124
old_options = dataclasses.asdict(
124125
self.field_options.get(name, self.default_field_options)
125126
)
126127
self.field_options[name] = FieldOptions(**(old_options | kwargs))
127-
return self
128+
return self
128129

129130
def default_field(self, **kwargs: str) -> RendererContext:
130131
self.default_field_options = FieldOptions(

wtforms_bootstrap5/renderers.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,29 @@ def wrap_with(
4848
if class_name is not None:
4949
kwargs["class"] = class_name
5050
kwargs.update(attrs)
51-
return Markup(f"<{tag}{html_params(**kwargs)}>{html}</div>")
51+
return Markup(f"<{tag}{html_params(**kwargs)}>{html}</{tag}>")
5252

5353

5454
@register(target_cls=Form)
5555
def render_form(context: RendererContext, element: FormElement) -> Markup:
5656
form: Form = element
57+
form_options = context.form_options
5758
fields = [context.render(field) for field in form._fields.values()]
58-
# TODO: add form action, method and other stuff
59-
return Markup("<form>" + "\n".join(fields) + "</form>")
59+
content = "\n".join(fields)
60+
base_attrs = {}
61+
if form_options.action is not None:
62+
base_attrs["action"] = form_options.action
63+
if form_options.method is not None:
64+
base_attrs["method"] = form_options.method
65+
if form_options.enctype is not None:
66+
base_attrs["enctype"] = form_options.enctype
67+
return wrap_with(
68+
content,
69+
enabled=form_options.form_enabled,
70+
class_name=form_options.form_class,
71+
attrs=base_attrs | form_options.form_attrs,
72+
tag="form",
73+
)
6074

6175

6276
@register(target_cls=Field)

0 commit comments

Comments
 (0)