test_selectdatewidget.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. from datetime import date
  2. from django.forms import DateField, Form, SelectDateWidget
  3. from django.test import ignore_warnings, override_settings
  4. from django.utils import translation
  5. from django.utils.dates import MONTHS_AP
  6. from django.utils.deprecation import RemovedInDjango50Warning
  7. from .base import WidgetTest
  8. class SelectDateWidgetTest(WidgetTest):
  9. maxDiff = None
  10. widget = SelectDateWidget(
  11. years=(
  12. "2007",
  13. "2008",
  14. "2009",
  15. "2010",
  16. "2011",
  17. "2012",
  18. "2013",
  19. "2014",
  20. "2015",
  21. "2016",
  22. ),
  23. )
  24. def test_render_empty(self):
  25. self.check_html(
  26. self.widget,
  27. "mydate",
  28. "",
  29. html=(
  30. """
  31. <select name="mydate_month" id="id_mydate_month">
  32. <option selected value="">---</option>
  33. <option value="1">January</option>
  34. <option value="2">February</option>
  35. <option value="3">March</option>
  36. <option value="4">April</option>
  37. <option value="5">May</option>
  38. <option value="6">June</option>
  39. <option value="7">July</option>
  40. <option value="8">August</option>
  41. <option value="9">September</option>
  42. <option value="10">October</option>
  43. <option value="11">November</option>
  44. <option value="12">December</option>
  45. </select>
  46. <select name="mydate_day" id="id_mydate_day">
  47. <option selected value="">---</option>
  48. <option value="1">1</option>
  49. <option value="2">2</option>
  50. <option value="3">3</option>
  51. <option value="4">4</option>
  52. <option value="5">5</option>
  53. <option value="6">6</option>
  54. <option value="7">7</option>
  55. <option value="8">8</option>
  56. <option value="9">9</option>
  57. <option value="10">10</option>
  58. <option value="11">11</option>
  59. <option value="12">12</option>
  60. <option value="13">13</option>
  61. <option value="14">14</option>
  62. <option value="15">15</option>
  63. <option value="16">16</option>
  64. <option value="17">17</option>
  65. <option value="18">18</option>
  66. <option value="19">19</option>
  67. <option value="20">20</option>
  68. <option value="21">21</option>
  69. <option value="22">22</option>
  70. <option value="23">23</option>
  71. <option value="24">24</option>
  72. <option value="25">25</option>
  73. <option value="26">26</option>
  74. <option value="27">27</option>
  75. <option value="28">28</option>
  76. <option value="29">29</option>
  77. <option value="30">30</option>
  78. <option value="31">31</option>
  79. </select>
  80. <select name="mydate_year" id="id_mydate_year">
  81. <option selected value="">---</option>
  82. <option value="2007">2007</option>
  83. <option value="2008">2008</option>
  84. <option value="2009">2009</option>
  85. <option value="2010">2010</option>
  86. <option value="2011">2011</option>
  87. <option value="2012">2012</option>
  88. <option value="2013">2013</option>
  89. <option value="2014">2014</option>
  90. <option value="2015">2015</option>
  91. <option value="2016">2016</option>
  92. </select>
  93. """
  94. ),
  95. )
  96. def test_render_none(self):
  97. """
  98. Rendering the None or '' values should yield the same output.
  99. """
  100. self.assertHTMLEqual(
  101. self.widget.render("mydate", None),
  102. self.widget.render("mydate", ""),
  103. )
  104. def test_render_string(self):
  105. self.check_html(
  106. self.widget,
  107. "mydate",
  108. "2010-04-15",
  109. html=(
  110. """
  111. <select name="mydate_month" id="id_mydate_month">
  112. <option value="">---</option>
  113. <option value="1">January</option>
  114. <option value="2">February</option>
  115. <option value="3">March</option>
  116. <option value="4" selected>April</option>
  117. <option value="5">May</option>
  118. <option value="6">June</option>
  119. <option value="7">July</option>
  120. <option value="8">August</option>
  121. <option value="9">September</option>
  122. <option value="10">October</option>
  123. <option value="11">November</option>
  124. <option value="12">December</option>
  125. </select>
  126. <select name="mydate_day" id="id_mydate_day">
  127. <option value="">---</option>
  128. <option value="1">1</option>
  129. <option value="2">2</option>
  130. <option value="3">3</option>
  131. <option value="4">4</option>
  132. <option value="5">5</option>
  133. <option value="6">6</option>
  134. <option value="7">7</option>
  135. <option value="8">8</option>
  136. <option value="9">9</option>
  137. <option value="10">10</option>
  138. <option value="11">11</option>
  139. <option value="12">12</option>
  140. <option value="13">13</option>
  141. <option value="14">14</option>
  142. <option value="15" selected>15</option>
  143. <option value="16">16</option>
  144. <option value="17">17</option>
  145. <option value="18">18</option>
  146. <option value="19">19</option>
  147. <option value="20">20</option>
  148. <option value="21">21</option>
  149. <option value="22">22</option>
  150. <option value="23">23</option>
  151. <option value="24">24</option>
  152. <option value="25">25</option>
  153. <option value="26">26</option>
  154. <option value="27">27</option>
  155. <option value="28">28</option>
  156. <option value="29">29</option>
  157. <option value="30">30</option>
  158. <option value="31">31</option>
  159. </select>
  160. <select name="mydate_year" id="id_mydate_year">
  161. <option value="">---</option>
  162. <option value="2007">2007</option>
  163. <option value="2008">2008</option>
  164. <option value="2009">2009</option>
  165. <option value="2010" selected>2010</option>
  166. <option value="2011">2011</option>
  167. <option value="2012">2012</option>
  168. <option value="2013">2013</option>
  169. <option value="2014">2014</option>
  170. <option value="2015">2015</option>
  171. <option value="2016">2016</option>
  172. </select>
  173. """
  174. ),
  175. )
  176. def test_render_datetime(self):
  177. self.assertHTMLEqual(
  178. self.widget.render("mydate", date(2010, 4, 15)),
  179. self.widget.render("mydate", "2010-04-15"),
  180. )
  181. def test_render_invalid_date(self):
  182. """
  183. Invalid dates should still render the failed date.
  184. """
  185. self.check_html(
  186. self.widget,
  187. "mydate",
  188. "2010-02-31",
  189. html=(
  190. """
  191. <select name="mydate_month" id="id_mydate_month">
  192. <option value="">---</option>
  193. <option value="1">January</option>
  194. <option value="2" selected>February</option>
  195. <option value="3">March</option>
  196. <option value="4">April</option>
  197. <option value="5">May</option>
  198. <option value="6">June</option>
  199. <option value="7">July</option>
  200. <option value="8">August</option>
  201. <option value="9">September</option>
  202. <option value="10">October</option>
  203. <option value="11">November</option>
  204. <option value="12">December</option>
  205. </select>
  206. <select name="mydate_day" id="id_mydate_day">
  207. <option value="">---</option>
  208. <option value="1">1</option>
  209. <option value="2">2</option>
  210. <option value="3">3</option>
  211. <option value="4">4</option>
  212. <option value="5">5</option>
  213. <option value="6">6</option>
  214. <option value="7">7</option>
  215. <option value="8">8</option>
  216. <option value="9">9</option>
  217. <option value="10">10</option>
  218. <option value="11">11</option>
  219. <option value="12">12</option>
  220. <option value="13">13</option>
  221. <option value="14">14</option>
  222. <option value="15">15</option>
  223. <option value="16">16</option>
  224. <option value="17">17</option>
  225. <option value="18">18</option>
  226. <option value="19">19</option>
  227. <option value="20">20</option>
  228. <option value="21">21</option>
  229. <option value="22">22</option>
  230. <option value="23">23</option>
  231. <option value="24">24</option>
  232. <option value="25">25</option>
  233. <option value="26">26</option>
  234. <option value="27">27</option>
  235. <option value="28">28</option>
  236. <option value="29">29</option>
  237. <option value="30">30</option>
  238. <option value="31" selected>31</option>
  239. </select>
  240. <select name="mydate_year" id="id_mydate_year">
  241. <option value="">---</option>
  242. <option value="2007">2007</option>
  243. <option value="2008">2008</option>
  244. <option value="2009">2009</option>
  245. <option value="2010" selected>2010</option>
  246. <option value="2011">2011</option>
  247. <option value="2012">2012</option>
  248. <option value="2013">2013</option>
  249. <option value="2014">2014</option>
  250. <option value="2015">2015</option>
  251. <option value="2016">2016</option>
  252. </select>
  253. """
  254. ),
  255. )
  256. def test_custom_months(self):
  257. widget = SelectDateWidget(months=MONTHS_AP, years=("2013",))
  258. self.check_html(
  259. widget,
  260. "mydate",
  261. "",
  262. html=(
  263. """
  264. <select name="mydate_month" id="id_mydate_month">
  265. <option selected value="">---</option>
  266. <option value="1">Jan.</option>
  267. <option value="2">Feb.</option>
  268. <option value="3">March</option>
  269. <option value="4">April</option>
  270. <option value="5">May</option>
  271. <option value="6">June</option>
  272. <option value="7">July</option>
  273. <option value="8">Aug.</option>
  274. <option value="9">Sept.</option>
  275. <option value="10">Oct.</option>
  276. <option value="11">Nov.</option>
  277. <option value="12">Dec.</option>
  278. </select>
  279. <select name="mydate_day" id="id_mydate_day">
  280. <option selected value="">---</option>
  281. <option value="1">1</option>
  282. <option value="2">2</option>
  283. <option value="3">3</option>
  284. <option value="4">4</option>
  285. <option value="5">5</option>
  286. <option value="6">6</option>
  287. <option value="7">7</option>
  288. <option value="8">8</option>
  289. <option value="9">9</option>
  290. <option value="10">10</option>
  291. <option value="11">11</option>
  292. <option value="12">12</option>
  293. <option value="13">13</option>
  294. <option value="14">14</option>
  295. <option value="15">15</option>
  296. <option value="16">16</option>
  297. <option value="17">17</option>
  298. <option value="18">18</option>
  299. <option value="19">19</option>
  300. <option value="20">20</option>
  301. <option value="21">21</option>
  302. <option value="22">22</option>
  303. <option value="23">23</option>
  304. <option value="24">24</option>
  305. <option value="25">25</option>
  306. <option value="26">26</option>
  307. <option value="27">27</option>
  308. <option value="28">28</option>
  309. <option value="29">29</option>
  310. <option value="30">30</option>
  311. <option value="31">31</option>
  312. </select>
  313. <select name="mydate_year" id="id_mydate_year">
  314. <option selected value="">---</option>
  315. <option value="2013">2013</option>
  316. </select>
  317. """
  318. ),
  319. )
  320. def test_selectdate_required(self):
  321. class GetNotRequiredDate(Form):
  322. mydate = DateField(widget=SelectDateWidget, required=False)
  323. class GetRequiredDate(Form):
  324. mydate = DateField(widget=SelectDateWidget, required=True)
  325. self.assertFalse(GetNotRequiredDate().fields["mydate"].widget.is_required)
  326. self.assertTrue(GetRequiredDate().fields["mydate"].widget.is_required)
  327. def test_selectdate_empty_label(self):
  328. w = SelectDateWidget(years=("2014",), empty_label="empty_label")
  329. # Rendering the default state with empty_label set as string.
  330. self.assertInHTML(
  331. '<option selected value="">empty_label</option>',
  332. w.render("mydate", ""),
  333. count=3,
  334. )
  335. w = SelectDateWidget(
  336. years=("2014",), empty_label=("empty_year", "empty_month", "empty_day")
  337. )
  338. # Rendering the default state with empty_label tuple.
  339. self.assertHTMLEqual(
  340. w.render("mydate", ""),
  341. """
  342. <select name="mydate_month" id="id_mydate_month">
  343. <option selected value="">empty_month</option>
  344. <option value="1">January</option>
  345. <option value="2">February</option>
  346. <option value="3">March</option>
  347. <option value="4">April</option>
  348. <option value="5">May</option>
  349. <option value="6">June</option>
  350. <option value="7">July</option>
  351. <option value="8">August</option>
  352. <option value="9">September</option>
  353. <option value="10">October</option>
  354. <option value="11">November</option>
  355. <option value="12">December</option>
  356. </select>
  357. <select name="mydate_day" id="id_mydate_day">
  358. <option selected value="">empty_day</option>
  359. <option value="1">1</option>
  360. <option value="2">2</option>
  361. <option value="3">3</option>
  362. <option value="4">4</option>
  363. <option value="5">5</option>
  364. <option value="6">6</option>
  365. <option value="7">7</option>
  366. <option value="8">8</option>
  367. <option value="9">9</option>
  368. <option value="10">10</option>
  369. <option value="11">11</option>
  370. <option value="12">12</option>
  371. <option value="13">13</option>
  372. <option value="14">14</option>
  373. <option value="15">15</option>
  374. <option value="16">16</option>
  375. <option value="17">17</option>
  376. <option value="18">18</option>
  377. <option value="19">19</option>
  378. <option value="20">20</option>
  379. <option value="21">21</option>
  380. <option value="22">22</option>
  381. <option value="23">23</option>
  382. <option value="24">24</option>
  383. <option value="25">25</option>
  384. <option value="26">26</option>
  385. <option value="27">27</option>
  386. <option value="28">28</option>
  387. <option value="29">29</option>
  388. <option value="30">30</option>
  389. <option value="31">31</option>
  390. </select>
  391. <select name="mydate_year" id="id_mydate_year">
  392. <option selected value="">empty_year</option>
  393. <option value="2014">2014</option>
  394. </select>
  395. """,
  396. )
  397. with self.assertRaisesMessage(
  398. ValueError, "empty_label list/tuple must have 3 elements."
  399. ):
  400. SelectDateWidget(years=("2014",), empty_label=("not enough", "values"))
  401. @translation.override("nl")
  402. def test_l10n(self):
  403. w = SelectDateWidget(
  404. years=(
  405. "2007",
  406. "2008",
  407. "2009",
  408. "2010",
  409. "2011",
  410. "2012",
  411. "2013",
  412. "2014",
  413. "2015",
  414. "2016",
  415. )
  416. )
  417. self.assertEqual(
  418. w.value_from_datadict(
  419. {"date_year": "2010", "date_month": "8", "date_day": "13"}, {}, "date"
  420. ),
  421. "13-08-2010",
  422. )
  423. self.assertHTMLEqual(
  424. w.render("date", "13-08-2010"),
  425. """
  426. <select name="date_day" id="id_date_day">
  427. <option value="">---</option>
  428. <option value="1">1</option>
  429. <option value="2">2</option>
  430. <option value="3">3</option>
  431. <option value="4">4</option>
  432. <option value="5">5</option>
  433. <option value="6">6</option>
  434. <option value="7">7</option>
  435. <option value="8">8</option>
  436. <option value="9">9</option>
  437. <option value="10">10</option>
  438. <option value="11">11</option>
  439. <option value="12">12</option>
  440. <option value="13" selected>13</option>
  441. <option value="14">14</option>
  442. <option value="15">15</option>
  443. <option value="16">16</option>
  444. <option value="17">17</option>
  445. <option value="18">18</option>
  446. <option value="19">19</option>
  447. <option value="20">20</option>
  448. <option value="21">21</option>
  449. <option value="22">22</option>
  450. <option value="23">23</option>
  451. <option value="24">24</option>
  452. <option value="25">25</option>
  453. <option value="26">26</option>
  454. <option value="27">27</option>
  455. <option value="28">28</option>
  456. <option value="29">29</option>
  457. <option value="30">30</option>
  458. <option value="31">31</option>
  459. </select>
  460. <select name="date_month" id="id_date_month">
  461. <option value="">---</option>
  462. <option value="1">januari</option>
  463. <option value="2">februari</option>
  464. <option value="3">maart</option>
  465. <option value="4">april</option>
  466. <option value="5">mei</option>
  467. <option value="6">juni</option>
  468. <option value="7">juli</option>
  469. <option value="8" selected>augustus</option>
  470. <option value="9">september</option>
  471. <option value="10">oktober</option>
  472. <option value="11">november</option>
  473. <option value="12">december</option>
  474. </select>
  475. <select name="date_year" id="id_date_year">
  476. <option value="">---</option>
  477. <option value="2007">2007</option>
  478. <option value="2008">2008</option>
  479. <option value="2009">2009</option>
  480. <option value="2010" selected>2010</option>
  481. <option value="2011">2011</option>
  482. <option value="2012">2012</option>
  483. <option value="2013">2013</option>
  484. <option value="2014">2014</option>
  485. <option value="2015">2015</option>
  486. <option value="2016">2016</option>
  487. </select>
  488. """,
  489. )
  490. # Even with an invalid date, the widget should reflect the entered
  491. # value.
  492. self.assertEqual(w.render("mydate", "2010-02-30").count("selected"), 3)
  493. # Years before 1900 should work.
  494. w = SelectDateWidget(years=("1899",))
  495. self.assertEqual(
  496. w.value_from_datadict(
  497. {"date_year": "1899", "date_month": "8", "date_day": "13"}, {}, "date"
  498. ),
  499. "13-08-1899",
  500. )
  501. # And years before 1000 (demonstrating the need for
  502. # sanitize_strftime_format).
  503. w = SelectDateWidget(years=("0001",))
  504. self.assertEqual(
  505. w.value_from_datadict(
  506. {"date_year": "0001", "date_month": "8", "date_day": "13"}, {}, "date"
  507. ),
  508. "13-08-0001",
  509. )
  510. # RemovedInDjango50Warning: When the deprecation ends, remove
  511. # @ignore_warnings and USE_L10N=False. The test should remain because
  512. # format-related settings will take precedence over locale-dictated
  513. # formats.
  514. @ignore_warnings(category=RemovedInDjango50Warning)
  515. @override_settings(USE_L10N=False, DATE_INPUT_FORMATS=["%d.%m.%Y"])
  516. def test_custom_input_format(self):
  517. w = SelectDateWidget(years=("0001", "1899", "2009", "2010"))
  518. for values, expected_value in (
  519. (("0001", "8", "13"), "13.08.0001"),
  520. (("1899", "7", "11"), "11.07.1899"),
  521. (("2009", "3", "7"), "07.03.2009"),
  522. ):
  523. with self.subTest(values=values):
  524. data = {
  525. "field_%s" % field: value
  526. for field, value in zip(("year", "month", "day"), values)
  527. }
  528. self.assertEqual(
  529. w.value_from_datadict(data, {}, "field"), expected_value
  530. )
  531. expected_dict = {
  532. field: int(value)
  533. for field, value in zip(("year", "month", "day"), values)
  534. }
  535. self.assertEqual(w.format_value(expected_value), expected_dict)
  536. def test_format_value(self):
  537. valid_formats = [
  538. "2000-1-1",
  539. "2000-10-15",
  540. "2000-01-01",
  541. "2000-01-0",
  542. "2000-0-01",
  543. "2000-0-0",
  544. "0-01-01",
  545. "0-01-0",
  546. "0-0-01",
  547. "0-0-0",
  548. ]
  549. for value in valid_formats:
  550. year, month, day = (int(x) or "" for x in value.split("-"))
  551. with self.subTest(value=value):
  552. self.assertEqual(
  553. self.widget.format_value(value),
  554. {"day": day, "month": month, "year": year},
  555. )
  556. invalid_formats = [
  557. "2000-01-001",
  558. "2000-001-01",
  559. "2-01-01",
  560. "20-01-01",
  561. "200-01-01",
  562. "20000-01-01",
  563. ]
  564. for value in invalid_formats:
  565. with self.subTest(value=value):
  566. self.assertEqual(
  567. self.widget.format_value(value),
  568. {"day": None, "month": None, "year": None},
  569. )
  570. def test_value_from_datadict(self):
  571. tests = [
  572. (("2000", "12", "1"), "2000-12-01"),
  573. (("", "12", "1"), "0-12-1"),
  574. (("2000", "", "1"), "2000-0-1"),
  575. (("2000", "12", ""), "2000-12-0"),
  576. (("", "", "", ""), None),
  577. ((None, "12", "1"), None),
  578. (("2000", None, "1"), None),
  579. (("2000", "12", None), None),
  580. ]
  581. for values, expected in tests:
  582. with self.subTest(values=values):
  583. data = {}
  584. for field_name, value in zip(("year", "month", "day"), values):
  585. if value is not None:
  586. data["field_%s" % field_name] = value
  587. self.assertEqual(
  588. self.widget.value_from_datadict(data, {}, "field"), expected
  589. )
  590. def test_value_omitted_from_data(self):
  591. self.assertIs(self.widget.value_omitted_from_data({}, {}, "field"), True)
  592. self.assertIs(
  593. self.widget.value_omitted_from_data({"field_month": "12"}, {}, "field"),
  594. False,
  595. )
  596. self.assertIs(
  597. self.widget.value_omitted_from_data({"field_year": "2000"}, {}, "field"),
  598. False,
  599. )
  600. self.assertIs(
  601. self.widget.value_omitted_from_data({"field_day": "1"}, {}, "field"), False
  602. )
  603. data = {"field_day": "1", "field_month": "12", "field_year": "2000"}
  604. self.assertIs(self.widget.value_omitted_from_data(data, {}, "field"), False)
  605. @override_settings(USE_THOUSAND_SEPARATOR=True)
  606. def test_years_rendered_without_separator(self):
  607. widget = SelectDateWidget(years=(2007,))
  608. self.check_html(
  609. widget,
  610. "mydate",
  611. "",
  612. html=(
  613. """
  614. <select name="mydate_month" id="id_mydate_month">
  615. <option selected value="">---</option>
  616. <option value="1">January</option>
  617. <option value="2">February</option>
  618. <option value="3">March</option>
  619. <option value="4">April</option>
  620. <option value="5">May</option>
  621. <option value="6">June</option>
  622. <option value="7">July</option>
  623. <option value="8">August</option>
  624. <option value="9">September</option>
  625. <option value="10">October</option>
  626. <option value="11">November</option>
  627. <option value="12">December</option>
  628. </select>
  629. <select name="mydate_day" id="id_mydate_day">
  630. <option selected value="">---</option>
  631. <option value="1">1</option>
  632. <option value="2">2</option>
  633. <option value="3">3</option>
  634. <option value="4">4</option>
  635. <option value="5">5</option>
  636. <option value="6">6</option>
  637. <option value="7">7</option>
  638. <option value="8">8</option>
  639. <option value="9">9</option>
  640. <option value="10">10</option>
  641. <option value="11">11</option>
  642. <option value="12">12</option>
  643. <option value="13">13</option>
  644. <option value="14">14</option>
  645. <option value="15">15</option>
  646. <option value="16">16</option>
  647. <option value="17">17</option>
  648. <option value="18">18</option>
  649. <option value="19">19</option>
  650. <option value="20">20</option>
  651. <option value="21">21</option>
  652. <option value="22">22</option>
  653. <option value="23">23</option>
  654. <option value="24">24</option>
  655. <option value="25">25</option>
  656. <option value="26">26</option>
  657. <option value="27">27</option>
  658. <option value="28">28</option>
  659. <option value="29">29</option>
  660. <option value="30">30</option>
  661. <option value="31">31</option>
  662. </select>
  663. <select name="mydate_year" id="id_mydate_year">
  664. <option selected value="">---</option>
  665. <option value="2007">2007</option>
  666. </select>
  667. """
  668. ),
  669. )
  670. def test_fieldset(self):
  671. class TestForm(Form):
  672. template_name = "forms_tests/use_fieldset.html"
  673. field = DateField(widget=self.widget)
  674. form = TestForm()
  675. self.assertIs(self.widget.use_fieldset, True)
  676. self.assertHTMLEqual(
  677. '<div><fieldset><legend for="id_field_month">Field:</legend>'
  678. '<select name="field_month" required id="id_field_month">'
  679. '<option value="1">January</option><option value="2">February</option>'
  680. '<option value="3">March</option><option value="4">April</option>'
  681. '<option value="5">May</option><option value="6">June</option>'
  682. '<option value="7">July</option><option value="8">August</option>'
  683. '<option value="9">September</option><option value="10">October</option>'
  684. '<option value="11">November</option><option value="12">December</option>'
  685. '</select><select name="field_day" required id="id_field_day">'
  686. '<option value="1">1</option><option value="2">2</option>'
  687. '<option value="3">3</option><option value="4">4</option>'
  688. '<option value="5">5</option><option value="6">6</option>'
  689. '<option value="7">7</option><option value="8">8</option>'
  690. '<option value="9">9</option><option value="10">10</option>'
  691. '<option value="11">11</option><option value="12">12</option>'
  692. '<option value="13">13</option><option value="14">14</option>'
  693. '<option value="15">15</option><option value="16">16</option>'
  694. '<option value="17">17</option><option value="18">18</option>'
  695. '<option value="19">19</option><option value="20">20</option>'
  696. '<option value="21">21</option><option value="22">22</option>'
  697. '<option value="23">23</option><option value="24">24</option>'
  698. '<option value="25">25</option><option value="26">26</option>'
  699. '<option value="27">27</option><option value="28">28</option>'
  700. '<option value="29">29</option><option value="30">30</option>'
  701. '<option value="31">31</option></select>'
  702. '<select name="field_year" required id="id_field_year">'
  703. '<option value="2007">2007</option><option value="2008">2008</option>'
  704. '<option value="2009">2009</option><option value="2010">2010</option>'
  705. '<option value="2011">2011</option><option value="2012">2012</option>'
  706. '<option value="2013">2013</option><option value="2014">2014</option>'
  707. '<option value="2015">2015</option><option value="2016">2016</option>'
  708. "</select></fieldset></div>",
  709. form.render(),
  710. )