mirror of
https://github.com/django/django.git
synced 2025-08-03 18:38:50 +00:00
Rewrote form widget tests as proper unittests.
This is preparation for landing the template-based widget rendering patch and goes a long way to making these tests more useful for future development. The old doctest heritage is strong here.
This commit is contained in:
parent
5153a3bfdc
commit
4c30fa905d
26 changed files with 2270 additions and 1825 deletions
163
tests/forms_tests/widget_tests/test_multiwidget.py
Normal file
163
tests/forms_tests/widget_tests/test_multiwidget.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
import copy
|
||||
from datetime import datetime
|
||||
|
||||
from django.forms import (
|
||||
CharField, FileInput, MultipleChoiceField, MultiValueField, MultiWidget,
|
||||
RadioSelect, SelectMultiple, SplitDateTimeField, SplitDateTimeWidget,
|
||||
TextInput,
|
||||
)
|
||||
|
||||
from .base import WidgetTest
|
||||
|
||||
|
||||
class MyMultiWidget(MultiWidget):
|
||||
def decompress(self, value):
|
||||
if value:
|
||||
return value.split('__')
|
||||
return ['', '']
|
||||
|
||||
|
||||
class ComplexMultiWidget(MultiWidget):
|
||||
def __init__(self, attrs=None):
|
||||
widgets = (
|
||||
TextInput(),
|
||||
SelectMultiple(choices=WidgetTest.beatles),
|
||||
SplitDateTimeWidget(),
|
||||
)
|
||||
super(ComplexMultiWidget, self).__init__(widgets, attrs)
|
||||
|
||||
def decompress(self, value):
|
||||
if value:
|
||||
data = value.split(',')
|
||||
return [
|
||||
data[0], list(data[1]), datetime.strptime(data[2], "%Y-%m-%d %H:%M:%S")
|
||||
]
|
||||
return [None, None, None]
|
||||
|
||||
def format_output(self, rendered_widgets):
|
||||
return '\n'.join(rendered_widgets)
|
||||
|
||||
|
||||
class ComplexField(MultiValueField):
|
||||
def __init__(self, required=True, widget=None, label=None, initial=None):
|
||||
fields = (
|
||||
CharField(),
|
||||
MultipleChoiceField(choices=WidgetTest.beatles),
|
||||
SplitDateTimeField(),
|
||||
)
|
||||
super(ComplexField, self).__init__(
|
||||
fields, required, widget, label, initial,
|
||||
)
|
||||
|
||||
def compress(self, data_list):
|
||||
if data_list:
|
||||
return '%s,%s,%s' % (
|
||||
data_list[0], ''.join(data_list[1]), data_list[2],
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
class DeepCopyWidget(MultiWidget):
|
||||
"""
|
||||
Used to test MultiWidget.__deepcopy__().
|
||||
"""
|
||||
def __init__(self, choices=[]):
|
||||
widgets = [
|
||||
RadioSelect(choices=choices),
|
||||
TextInput,
|
||||
]
|
||||
super(DeepCopyWidget, self).__init__(widgets)
|
||||
|
||||
def _set_choices(self, choices):
|
||||
"""
|
||||
When choices are set for this widget, we want to pass those along to
|
||||
the Select widget.
|
||||
"""
|
||||
self.widgets[0].choices = choices
|
||||
|
||||
def _get_choices(self):
|
||||
"""
|
||||
The choices for this widget are the Select widget's choices.
|
||||
"""
|
||||
return self.widgets[0].choices
|
||||
choices = property(_get_choices, _set_choices)
|
||||
|
||||
|
||||
class MultiWidgetTest(WidgetTest):
|
||||
|
||||
def test_text_inputs(self):
|
||||
widget = MyMultiWidget(
|
||||
widgets=(
|
||||
TextInput(attrs={'class': 'big'}),
|
||||
TextInput(attrs={'class': 'small'}),
|
||||
)
|
||||
)
|
||||
self.check_html(widget, 'name', ['john', 'lennon'], html=(
|
||||
'<input type="text" class="big" value="john" name="name_0" />'
|
||||
'<input type="text" class="small" value="lennon" name="name_1" />'
|
||||
))
|
||||
self.check_html(widget, 'name', 'john__lennon', html=(
|
||||
'<input type="text" class="big" value="john" name="name_0" />'
|
||||
'<input type="text" class="small" value="lennon" name="name_1" />'
|
||||
))
|
||||
self.check_html(widget, 'name', 'john__lennon', attrs={'id': 'foo'}, html=(
|
||||
'<input id="foo_0" type="text" class="big" value="john" name="name_0" />'
|
||||
'<input id="foo_1" type="text" class="small" value="lennon" name="name_1" />'
|
||||
))
|
||||
|
||||
def test_constructor_attrs(self):
|
||||
widget = MyMultiWidget(
|
||||
widgets=(
|
||||
TextInput(attrs={'class': 'big'}),
|
||||
TextInput(attrs={'class': 'small'}),
|
||||
),
|
||||
attrs={'id': 'bar'},
|
||||
)
|
||||
self.check_html(widget, 'name', ['john', 'lennon'], html=(
|
||||
'<input id="bar_0" type="text" class="big" value="john" name="name_0" />'
|
||||
'<input id="bar_1" type="text" class="small" value="lennon" name="name_1" />'
|
||||
))
|
||||
|
||||
def test_needs_multipart_true(self):
|
||||
"""
|
||||
needs_multipart_form should be True if any widgets need it.
|
||||
"""
|
||||
widget = MyMultiWidget(widgets=(TextInput(), FileInput()))
|
||||
self.assertTrue(widget.needs_multipart_form)
|
||||
|
||||
def test_needs_multipart_false(self):
|
||||
"""
|
||||
needs_multipart_form should be False if no widgets need it.
|
||||
"""
|
||||
widget = MyMultiWidget(widgets=(TextInput(), TextInput()))
|
||||
self.assertFalse(widget.needs_multipart_form)
|
||||
|
||||
def test_nested_multiwidget(self):
|
||||
"""
|
||||
MultiWidgets can be composed of other MultiWidgets.
|
||||
"""
|
||||
widget = ComplexMultiWidget()
|
||||
self.check_html(widget, 'name', 'some text,JP,2007-04-25 06:24:00', html=(
|
||||
"""
|
||||
<input type="text" name="name_0" value="some text" />
|
||||
<select multiple="multiple" name="name_1">
|
||||
<option value="J" selected="selected">John</option>
|
||||
<option value="P" selected="selected">Paul</option>
|
||||
<option value="G">George</option>
|
||||
<option value="R">Ringo</option>
|
||||
</select>
|
||||
<input type="text" name="name_2_0" value="2007-04-25" />
|
||||
<input type="text" name="name_2_1" value="06:24:00" />
|
||||
"""
|
||||
))
|
||||
|
||||
def test_deepcopy(self):
|
||||
"""
|
||||
MultiWidget should define __deepcopy__() (#12048).
|
||||
"""
|
||||
w1 = DeepCopyWidget(choices=[1, 2, 3])
|
||||
w2 = copy.deepcopy(w1)
|
||||
w2.choices = [4, 5, 6]
|
||||
# w2 ought to be independent of w1, since MultiWidget ought
|
||||
# to make a copy of its sub-widgets when it is copied.
|
||||
self.assertEqual(w1.choices, [1, 2, 3])
|
Loading…
Add table
Add a link
Reference in a new issue