import datetime from django.forms import ChoiceField, Form, MultiWidget, RadioSelect, TextInput from django.test import override_settings from django.utils.safestring import mark_safe from .test_choicewidget import ChoiceWidgetTest BLANK_CHOICE_DASH = (("", "------"),) class RadioSelectTest(ChoiceWidgetTest): widget = RadioSelect def test_render(self): html = """
""" beatles_with_blank = BLANK_CHOICE_DASH + self.beatles for choices in (beatles_with_blank, dict(beatles_with_blank)): with self.subTest(choices): self.check_html(self.widget(choices=choices), "beatle", "J", html=html) def test_nested_choices(self): nested_choices = ( ("unknown", "Unknown"), ("Audio", (("vinyl", "Vinyl"), ("cd", "CD"))), ("Video", (("vhs", "VHS"), ("dvd", "DVD"))), ) html = """
""" self.check_html( self.widget(choices=nested_choices), "nestchoice", "dvd", attrs={"id": "media"}, html=html, ) def test_render_none(self): """ If value is None, none of the options are selected. """ choices = BLANK_CHOICE_DASH + self.beatles html = """
""" self.check_html(self.widget(choices=choices), "beatle", None, html=html) def test_render_label_value(self): """ If the value corresponds to a label (but not to an option value), none of the options are selected. """ html = """
""" self.check_html(self.widget(choices=self.beatles), "beatle", "Ringo", html=html) def test_render_selected(self): """ Only one option can be selected. """ choices = [("0", "0"), ("1", "1"), ("2", "2"), ("3", "3"), ("0", "extra")] html = """
""" self.check_html(self.widget(choices=choices), "choices", "0", html=html) def test_constructor_attrs(self): """ Attributes provided at instantiation are passed to the constituent inputs. """ widget = self.widget(attrs={"id": "foo"}, choices=self.beatles) html = """
""" self.check_html(widget, "beatle", "J", html=html) def test_compare_to_str(self): """ The value is compared to its str(). """ html = """
""" self.check_html( self.widget(choices=[("1", "1"), ("2", "2"), ("3", "3")]), "num", 3, html=html, ) self.check_html( self.widget(choices=[(1, 1), (2, 2), (3, 3)]), "num", "3", html=html ) self.check_html( self.widget(choices=[(1, 1), (2, 2), (3, 3)]), "num", 3, html=html ) def test_choices_constructor(self): widget = self.widget(choices=[(1, 1), (2, 2), (3, 3)]) html = """
""" self.check_html(widget, "num", 3, html=html) def test_choices_constructor_generator(self): """ If choices is passed to the constructor and is a generator, it can be iterated over multiple times without getting consumed. """ def get_choices(): for i in range(4): yield (i, i) html = """
""" widget = self.widget(choices=get_choices()) self.check_html(widget, "num", 3, html=html) def test_choices_escaping(self): choices = (("bad", "you & me"), ("good", mark_safe("you > me"))) html = """
""" self.check_html(self.widget(choices=choices), "escape", None, html=html) def test_choices_unicode(self): html = """
""" self.check_html( self.widget(choices=[("ŠĐĆŽćžšđ", "ŠĐabcĆŽćžšđ"), ("ćžšđ", "abcćžšđ")]), "email", "ŠĐĆŽćžšđ", html=html, ) def test_choices_optgroup(self): """ Choices can be nested one level in order to create HTML optgroups. """ html = """
""" for widget in self.nested_widgets: with self.subTest(widget): self.check_html(widget, "nestchoice", None, html=html) def test_choices_select_outer(self): html = """
""" for widget in self.nested_widgets: with self.subTest(widget): self.check_html(widget, "nestchoice", "outer1", html=html) def test_choices_select_inner(self): html = """
""" for widget in self.nested_widgets: with self.subTest(widget): self.check_html(widget, "nestchoice", "inner2", html=html) def test_render_attrs(self): """ Attributes provided at render-time are passed to the constituent inputs. """ html = """
""" self.check_html( self.widget(choices=self.beatles), "beatle", "J", attrs={"id": "bar"}, html=html, ) def test_class_attrs(self): """ The
in the multiple_input.html widget template include the class attribute. """ html = """
""" self.check_html( self.widget(choices=self.beatles), "beatle", "J", attrs={"class": "bar"}, html=html, ) @override_settings(USE_THOUSAND_SEPARATOR=True) def test_doesnt_localize_input_value(self): choices = [ (1, "One"), (1000, "One thousand"), (1000000, "One million"), ] html = """
""" self.check_html(self.widget(choices=choices), "number", None, html=html) choices = [ (datetime.time(0, 0), "midnight"), (datetime.time(12, 0), "noon"), ] html = """
""" self.check_html(self.widget(choices=choices), "time", None, html=html) def test_render_as_subwidget(self): """A RadioSelect as a subwidget of MultiWidget.""" choices = BLANK_CHOICE_DASH + self.beatles html = """
""" self.check_html( MultiWidget([self.widget(choices=choices), TextInput()]), "beatle", ["J", "Some text"], html=html, ) def test_fieldset(self): class TestForm(Form): template_name = "forms_tests/use_fieldset.html" field = ChoiceField( widget=self.widget, choices=self.beatles, required=False ) form = TestForm() self.assertIs(self.widget.use_fieldset, True) self.assertHTMLEqual( '
Field:
' '
' '
' "
", form.render(), )