123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- # -*- 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(choices=self.beatles), 'beatle', 'J', html=(
- """<select name="beatle">
- <option value="J" selected>John</option>
- <option value="P">Paul</option>
- <option value="G">George</option>
- <option value="R">Ringo</option>
- </select>"""
- ))
- def test_render_none(self):
- """
- If the value is None, none of the options are selected.
- """
- self.check_html(self.widget(choices=self.beatles), 'beatle', None, html=(
- """<select name="beatle">
- <option value="J">John</option>
- <option value="P">Paul</option>
- <option value="G">George</option>
- <option value="R">Ringo</option>
- </select>"""
- ))
- 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(choices=self.beatles), 'beatle', 'John', html=(
- """<select name="beatle">
- <option value="J">John</option>
- <option value="P">Paul</option>
- <option value="G">George</option>
- <option value="R">Ringo</option>
- </select>"""
- ))
- 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=choices), 'choices', '0', html=(
- """<select name="choices">
- <option value="0" selected>0</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="0">extra</option>
- </select>"""
- ))
- 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=(
- """<select name="num" class="super" id="super">
- <option value="1">1</option>
- <option value="2" selected>2</option>
- <option value="3">3</option>
- </select>"""
- ))
- def test_compare_to_str(self):
- """
- The value is compared to its str().
- """
- self.check_html(
- self.widget(choices=[('1', '1'), ('2', '2'), ('3', '3')]),
- 'num', 2,
- html=(
- """<select name="num">
- <option value="1">1</option>
- <option value="2" selected>2</option>
- <option value="3">3</option>
- </select>"""
- ),
- )
- self.check_html(
- self.widget(choices=[(1, 1), (2, 2), (3, 3)]),
- 'num', '2',
- html=(
- """<select name="num">
- <option value="1">1</option>
- <option value="2" selected>2</option>
- <option value="3">3</option>
- </select>"""
- ),
- )
- self.check_html(
- self.widget(choices=[(1, 1), (2, 2), (3, 3)]),
- 'num', 2,
- html=(
- """<select name="num">
- <option value="1">1</option>
- <option value="2" selected>2</option>
- <option value="3">3</option>
- </select>"""
- ),
- )
- def test_choices_constuctor(self):
- widget = Select(choices=[(1, 1), (2, 2), (3, 3)])
- self.check_html(widget, 'num', 2, html=(
- """<select name="num">
- <option value="1">1</option>
- <option value="2" selected>2</option>
- <option value="3">3</option>
- </select>"""
- ))
- 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=(
- """<select name="num">
- <option value="0">0</option>
- <option value="1">1</option>
- <option value="2" selected>2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- </select>"""
- ))
- self.check_html(widget, 'num', 3, html=(
- """<select name="num">
- <option value="0">0</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3" selected>3</option>
- <option value="4">4</option>
- </select>"""
- ))
- def test_choices_escaping(self):
- choices = (('bad', 'you & me'), ('good', mark_safe('you > me')))
- self.check_html(self.widget(choices=choices), 'escape', None, html=(
- """<select name="escape">
- <option value="bad">you & me</option>
- <option value="good">you > me</option>
- </select>"""
- ))
- def test_choices_unicode(self):
- self.check_html(
- self.widget(choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]),
- 'email', 'ŠĐĆŽćžšđ',
- html=(
- """<select name="email">
- <option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected>
- \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111
- </option>
- <option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>
- </select>"""
- ),
- )
- 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=(
- """<select name="nestchoice">
- <option value="outer1">Outer 1</option>
- <optgroup label="Group "1"">
- <option value="inner1">Inner 1</option>
- <option value="inner2">Inner 2</option>
- </optgroup>
- </select>"""
- ))
- def test_choices_select_outer(self):
- self.check_html(self.nested_widget, 'nestchoice', 'outer1', html=(
- """<select name="nestchoice">
- <option value="outer1" selected>Outer 1</option>
- <optgroup label="Group "1"">
- <option value="inner1">Inner 1</option>
- <option value="inner2">Inner 2</option>
- </optgroup>
- </select>"""
- ))
- def test_choices_select_inner(self):
- self.check_html(self.nested_widget, 'nestchoice', 'inner1', html=(
- """<select name="nestchoice">
- <option value="outer1">Outer 1</option>
- <optgroup label="Group "1"">
- <option value="inner1" selected>Inner 1</option>
- <option value="inner2">Inner 2</option>
- </optgroup>
- </select>"""
- ))
- def test_options(self):
- options = list(self.widget(choices=self.beatles).options(
- 'name', ['J'], attrs={'class': 'super'},
- ))
- self.assertEqual(len(options), 4)
- self.assertEqual(options[0]['name'], 'name')
- self.assertEqual(options[0]['value'], 'J')
- self.assertEqual(options[0]['label'], 'John')
- self.assertEqual(options[0]['index'], '0')
- self.assertEqual(options[0]['selected'], True)
- # Template-related attributes
- self.assertEqual(options[1]['name'], 'name')
- self.assertEqual(options[1]['value'], 'P')
- self.assertEqual(options[1]['label'], 'Paul')
- self.assertEqual(options[1]['index'], '1')
- self.assertEqual(options[1]['selected'], False)
- def test_optgroups(self):
- choices = [
- ('Audio', [
- ('vinyl', 'Vinyl'),
- ('cd', 'CD'),
- ]),
- ('Video', [
- ('vhs', 'VHS Tape'),
- ('dvd', 'DVD'),
- ]),
- ('unknown', 'Unknown'),
- ]
- groups = list(self.widget(choices=choices).optgroups(
- 'name', ['vhs'], attrs={'class': 'super'},
- ))
- self.assertEqual(len(groups), 3)
- self.assertEqual(groups[0][0], None)
- self.assertEqual(groups[0][2], 0)
- self.assertEqual(len(groups[0][1]), 1)
- options = groups[0][1]
- self.assertEqual(options[0]['name'], 'name')
- self.assertEqual(options[0]['value'], 'unknown')
- self.assertEqual(options[0]['label'], 'Unknown')
- self.assertEqual(options[0]['index'], '0')
- self.assertEqual(options[0]['selected'], False)
- self.assertEqual(groups[1][0], 'Audio')
- self.assertEqual(groups[1][2], 1)
- self.assertEqual(len(groups[1][1]), 2)
- options = groups[1][1]
- self.assertEqual(options[0]['name'], 'name')
- self.assertEqual(options[0]['value'], 'vinyl')
- self.assertEqual(options[0]['label'], 'Vinyl')
- self.assertEqual(options[0]['index'], '1_0')
- self.assertEqual(options[1]['index'], '1_1')
- self.assertEqual(groups[2][0], 'Video')
- self.assertEqual(groups[2][2], 2)
- self.assertEqual(len(groups[2][1]), 2)
- options = groups[2][1]
- self.assertEqual(options[0]['name'], 'name')
- self.assertEqual(options[0]['value'], 'vhs')
- self.assertEqual(options[0]['label'], 'VHS Tape')
- self.assertEqual(options[0]['index'], '2_0')
- self.assertEqual(options[0]['selected'], True)
- self.assertEqual(options[1]['index'], '2_1')
- 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)
|