# -*- coding: utf-8 -*- from __future__ import unicode_literals import copy from django.forms import Select from django.utils.safestring import mark_safe from .base import WidgetTest class SelectTest(WidgetTest): widget = Select() nested_widget = Select(choices=( ('outer1', 'Outer 1'), ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2'))), )) def test_render(self): self.check_html(self.widget, 'beatle', 'J', choices=self.beatles, html=( """""" )) def test_render_none(self): """ If the value is None, none of the options are selected. """ self.check_html(self.widget, 'beatle', None, choices=self.beatles, 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. """ self.check_html(self.widget, 'beatle', 'John', choices=self.beatles, html=( """""" )) def test_render_selected(self): """ Only one option can be selected (#8103). """ choices = [('0', '0'), ('1', '1'), ('2', '2'), ('3', '3'), ('0', 'extra')] self.check_html(self.widget, 'choices', '0', choices=choices, html=( """""" )) def test_constructor_attrs(self): """ Select options shouldn't inherit the parent widget attrs. """ widget = Select( attrs={'class': 'super', 'id': 'super'}, choices=[(1, 1), (2, 2), (3, 3)], ) self.check_html(widget, 'num', 2, html=( """""" )) def test_compare_to_str(self): """ The value is compared to its str(). """ self.check_html( self.widget, 'num', 2, choices=[('1', '1'), ('2', '2'), ('3', '3')], html=( """""" ), ) self.check_html( self.widget, 'num', '2', choices=[(1, 1), (2, 2), (3, 3)], html=( """""" ), ) self.check_html( self.widget, 'num', 2, choices=[(1, 1), (2, 2), (3, 3)], html=( """""" ), ) def test_choices_constuctor(self): widget = Select(choices=[(1, 1), (2, 2), (3, 3)]) self.check_html(widget, 'num', 2, 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(5): yield (i, i) widget = Select(choices=get_choices()) self.check_html(widget, 'num', 2, html=( """""" )) self.check_html(widget, 'num', 3, html=( """""" )) def test_choices_constuctor_and_render(self): """ If 'choices' is passed to both the constructor and render(), then they'll both be in the output. """ widget = Select(choices=[(1, 1), (2, 2), (3, 3)]) self.check_html(widget, 'num', 2, choices=[(4, 4), (5, 5)], html=( """""" )) def test_choices_escaping(self): choices = (('bad', 'you & me'), ('good', mark_safe('you > me'))) self.check_html(self.widget, 'escape', None, choices=choices, html=( """""" )) def test_choices_unicode(self): self.check_html( self.widget, 'email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')], html=( """""" ), ) def test_choices_optgroup(self): """ Choices can be nested one level in order to create HTML optgroups. """ self.check_html(self.nested_widget, 'nestchoice', None, html=( """""" )) def test_choices_select_outer(self): self.check_html(self.nested_widget, 'nestchoice', 'outer1', html=( """""" )) def test_choices_select_inner(self): self.check_html(self.nested_widget, 'nestchoice', 'inner1', html=( """""" )) def test_deepcopy(self): """ __deepcopy__() should copy all attributes properly (#25085). """ widget = Select() obj = copy.deepcopy(widget) self.assertIsNot(widget, obj) self.assertEqual(widget.choices, obj.choices) self.assertIsNot(widget.choices, obj.choices) self.assertEqual(widget.attrs, obj.attrs) self.assertIsNot(widget.attrs, obj.attrs)