tests.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import, unicode_literals
  3. import unittest
  4. from unittest import skip
  5. from django.db import connection
  6. from django.forms import EmailField, IntegerField
  7. from django.http import HttpResponse
  8. from django.template.loader import render_to_string
  9. from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
  10. from django.test.html import HTMLParseError, parse_html
  11. from django.test.utils import CaptureQueriesContext, IgnoreDeprecationWarningsMixin
  12. from django.utils import six
  13. from .models import Person
  14. class SkippingTestCase(TestCase):
  15. def test_skip_unless_db_feature(self):
  16. "A test that might be skipped is actually called."
  17. # Total hack, but it works, just want an attribute that's always true.
  18. @skipUnlessDBFeature("__class__")
  19. def test_func():
  20. raise ValueError
  21. self.assertRaises(ValueError, test_func)
  22. class AssertNumQueriesTests(TestCase):
  23. urls = 'test_utils.urls'
  24. def test_assert_num_queries(self):
  25. def test_func():
  26. raise ValueError
  27. self.assertRaises(ValueError,
  28. self.assertNumQueries, 2, test_func
  29. )
  30. def test_assert_num_queries_with_client(self):
  31. person = Person.objects.create(name='test')
  32. self.assertNumQueries(
  33. 1,
  34. self.client.get,
  35. "/test_utils/get_person/%s/" % person.pk
  36. )
  37. self.assertNumQueries(
  38. 1,
  39. self.client.get,
  40. "/test_utils/get_person/%s/" % person.pk
  41. )
  42. def test_func():
  43. self.client.get("/test_utils/get_person/%s/" % person.pk)
  44. self.client.get("/test_utils/get_person/%s/" % person.pk)
  45. self.assertNumQueries(2, test_func)
  46. class AssertQuerysetEqualTests(TestCase):
  47. def setUp(self):
  48. self.p1 = Person.objects.create(name='p1')
  49. self.p2 = Person.objects.create(name='p2')
  50. def test_ordered(self):
  51. self.assertQuerysetEqual(
  52. Person.objects.all().order_by('name'),
  53. [repr(self.p1), repr(self.p2)]
  54. )
  55. def test_unordered(self):
  56. self.assertQuerysetEqual(
  57. Person.objects.all().order_by('name'),
  58. [repr(self.p2), repr(self.p1)],
  59. ordered=False
  60. )
  61. def test_transform(self):
  62. self.assertQuerysetEqual(
  63. Person.objects.all().order_by('name'),
  64. [self.p1.pk, self.p2.pk],
  65. transform=lambda x: x.pk
  66. )
  67. def test_undefined_order(self):
  68. # Using an unordered queryset with more than one ordered value
  69. # is an error.
  70. with self.assertRaises(ValueError):
  71. self.assertQuerysetEqual(
  72. Person.objects.all(),
  73. [repr(self.p1), repr(self.p2)]
  74. )
  75. # No error for one value.
  76. self.assertQuerysetEqual(
  77. Person.objects.filter(name='p1'),
  78. [repr(self.p1)]
  79. )
  80. class CaptureQueriesContextManagerTests(TestCase):
  81. urls = 'test_utils.urls'
  82. def setUp(self):
  83. self.person_pk = six.text_type(Person.objects.create(name='test').pk)
  84. def test_simple(self):
  85. with CaptureQueriesContext(connection) as captured_queries:
  86. Person.objects.get(pk=self.person_pk)
  87. self.assertEqual(len(captured_queries), 1)
  88. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  89. with CaptureQueriesContext(connection) as captured_queries:
  90. pass
  91. self.assertEqual(0, len(captured_queries))
  92. def test_within(self):
  93. with CaptureQueriesContext(connection) as captured_queries:
  94. Person.objects.get(pk=self.person_pk)
  95. self.assertEqual(len(captured_queries), 1)
  96. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  97. def test_nested(self):
  98. with CaptureQueriesContext(connection) as captured_queries:
  99. Person.objects.count()
  100. with CaptureQueriesContext(connection) as nested_captured_queries:
  101. Person.objects.count()
  102. self.assertEqual(1, len(nested_captured_queries))
  103. self.assertEqual(2, len(captured_queries))
  104. def test_failure(self):
  105. with self.assertRaises(TypeError):
  106. with CaptureQueriesContext(connection):
  107. raise TypeError
  108. def test_with_client(self):
  109. with CaptureQueriesContext(connection) as captured_queries:
  110. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  111. self.assertEqual(len(captured_queries), 1)
  112. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  113. with CaptureQueriesContext(connection) as captured_queries:
  114. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  115. self.assertEqual(len(captured_queries), 1)
  116. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  117. with CaptureQueriesContext(connection) as captured_queries:
  118. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  119. self.client.get("/test_utils/get_person/%s/" % self.person_pk)
  120. self.assertEqual(len(captured_queries), 2)
  121. self.assertIn(self.person_pk, captured_queries[0]['sql'])
  122. self.assertIn(self.person_pk, captured_queries[1]['sql'])
  123. class AssertNumQueriesContextManagerTests(TestCase):
  124. urls = 'test_utils.urls'
  125. def test_simple(self):
  126. with self.assertNumQueries(0):
  127. pass
  128. with self.assertNumQueries(1):
  129. Person.objects.count()
  130. with self.assertNumQueries(2):
  131. Person.objects.count()
  132. Person.objects.count()
  133. def test_failure(self):
  134. with self.assertRaises(AssertionError) as exc_info:
  135. with self.assertNumQueries(2):
  136. Person.objects.count()
  137. self.assertIn("1 queries executed, 2 expected", str(exc_info.exception))
  138. with self.assertRaises(TypeError):
  139. with self.assertNumQueries(4000):
  140. raise TypeError
  141. def test_with_client(self):
  142. person = Person.objects.create(name="test")
  143. with self.assertNumQueries(1):
  144. self.client.get("/test_utils/get_person/%s/" % person.pk)
  145. with self.assertNumQueries(1):
  146. self.client.get("/test_utils/get_person/%s/" % person.pk)
  147. with self.assertNumQueries(2):
  148. self.client.get("/test_utils/get_person/%s/" % person.pk)
  149. self.client.get("/test_utils/get_person/%s/" % person.pk)
  150. class AssertTemplateUsedContextManagerTests(TestCase):
  151. def test_usage(self):
  152. with self.assertTemplateUsed('template_used/base.html'):
  153. render_to_string('template_used/base.html')
  154. with self.assertTemplateUsed(template_name='template_used/base.html'):
  155. render_to_string('template_used/base.html')
  156. with self.assertTemplateUsed('template_used/base.html'):
  157. render_to_string('template_used/include.html')
  158. with self.assertTemplateUsed('template_used/base.html'):
  159. render_to_string('template_used/extends.html')
  160. with self.assertTemplateUsed('template_used/base.html'):
  161. render_to_string('template_used/base.html')
  162. render_to_string('template_used/base.html')
  163. def test_nested_usage(self):
  164. with self.assertTemplateUsed('template_used/base.html'):
  165. with self.assertTemplateUsed('template_used/include.html'):
  166. render_to_string('template_used/include.html')
  167. with self.assertTemplateUsed('template_used/extends.html'):
  168. with self.assertTemplateUsed('template_used/base.html'):
  169. render_to_string('template_used/extends.html')
  170. with self.assertTemplateUsed('template_used/base.html'):
  171. with self.assertTemplateUsed('template_used/alternative.html'):
  172. render_to_string('template_used/alternative.html')
  173. render_to_string('template_used/base.html')
  174. with self.assertTemplateUsed('template_used/base.html'):
  175. render_to_string('template_used/extends.html')
  176. with self.assertTemplateNotUsed('template_used/base.html'):
  177. render_to_string('template_used/alternative.html')
  178. render_to_string('template_used/base.html')
  179. def test_not_used(self):
  180. with self.assertTemplateNotUsed('template_used/base.html'):
  181. pass
  182. with self.assertTemplateNotUsed('template_used/alternative.html'):
  183. pass
  184. def test_error_message(self):
  185. with six.assertRaisesRegex(self, AssertionError, r'^template_used/base\.html'):
  186. with self.assertTemplateUsed('template_used/base.html'):
  187. pass
  188. with six.assertRaisesRegex(self, AssertionError, r'^template_used/base\.html'):
  189. with self.assertTemplateUsed(template_name='template_used/base.html'):
  190. pass
  191. with six.assertRaisesRegex(self, AssertionError, r'^template_used/base\.html.*template_used/alternative\.html$'):
  192. with self.assertTemplateUsed('template_used/base.html'):
  193. render_to_string('template_used/alternative.html')
  194. def test_failure(self):
  195. with self.assertRaises(TypeError):
  196. with self.assertTemplateUsed():
  197. pass
  198. with self.assertRaises(AssertionError):
  199. with self.assertTemplateUsed(''):
  200. pass
  201. with self.assertRaises(AssertionError):
  202. with self.assertTemplateUsed(''):
  203. render_to_string('template_used/base.html')
  204. with self.assertRaises(AssertionError):
  205. with self.assertTemplateUsed(template_name=''):
  206. pass
  207. with self.assertRaises(AssertionError):
  208. with self.assertTemplateUsed('template_used/base.html'):
  209. render_to_string('template_used/alternative.html')
  210. class HTMLEqualTests(TestCase):
  211. def test_html_parser(self):
  212. element = parse_html('<div><p>Hello</p></div>')
  213. self.assertEqual(len(element.children), 1)
  214. self.assertEqual(element.children[0].name, 'p')
  215. self.assertEqual(element.children[0].children[0], 'Hello')
  216. parse_html('<p>')
  217. parse_html('<p attr>')
  218. dom = parse_html('<p>foo')
  219. self.assertEqual(len(dom.children), 1)
  220. self.assertEqual(dom.name, 'p')
  221. self.assertEqual(dom[0], 'foo')
  222. def test_parse_html_in_script(self):
  223. parse_html('<script>var a = "<p" + ">";</script>');
  224. parse_html('''
  225. <script>
  226. var js_sha_link='<p>***</p>';
  227. </script>
  228. ''')
  229. # script content will be parsed to text
  230. dom = parse_html('''
  231. <script><p>foo</p> '</scr'+'ipt>' <span>bar</span></script>
  232. ''')
  233. self.assertEqual(len(dom.children), 1)
  234. self.assertEqual(dom.children[0], "<p>foo</p> '</scr'+'ipt>' <span>bar</span>")
  235. def test_self_closing_tags(self):
  236. self_closing_tags = ('br' , 'hr', 'input', 'img', 'meta', 'spacer',
  237. 'link', 'frame', 'base', 'col')
  238. for tag in self_closing_tags:
  239. dom = parse_html('<p>Hello <%s> world</p>' % tag)
  240. self.assertEqual(len(dom.children), 3)
  241. self.assertEqual(dom[0], 'Hello')
  242. self.assertEqual(dom[1].name, tag)
  243. self.assertEqual(dom[2], 'world')
  244. dom = parse_html('<p>Hello <%s /> world</p>' % tag)
  245. self.assertEqual(len(dom.children), 3)
  246. self.assertEqual(dom[0], 'Hello')
  247. self.assertEqual(dom[1].name, tag)
  248. self.assertEqual(dom[2], 'world')
  249. def test_simple_equal_html(self):
  250. self.assertHTMLEqual('', '')
  251. self.assertHTMLEqual('<p></p>', '<p></p>')
  252. self.assertHTMLEqual('<p></p>', ' <p> </p> ')
  253. self.assertHTMLEqual(
  254. '<div><p>Hello</p></div>',
  255. '<div><p>Hello</p></div>')
  256. self.assertHTMLEqual(
  257. '<div><p>Hello</p></div>',
  258. '<div> <p>Hello</p> </div>')
  259. self.assertHTMLEqual(
  260. '<div>\n<p>Hello</p></div>',
  261. '<div><p>Hello</p></div>\n')
  262. self.assertHTMLEqual(
  263. '<div><p>Hello\nWorld !</p></div>',
  264. '<div><p>Hello World\n!</p></div>')
  265. self.assertHTMLEqual(
  266. '<div><p>Hello\nWorld !</p></div>',
  267. '<div><p>Hello World\n!</p></div>')
  268. self.assertHTMLEqual(
  269. '<p>Hello World !</p>',
  270. '<p>Hello World\n\n!</p>')
  271. self.assertHTMLEqual('<p> </p>', '<p></p>')
  272. self.assertHTMLEqual('<p/>', '<p></p>')
  273. self.assertHTMLEqual('<p />', '<p></p>')
  274. self.assertHTMLEqual('<input checked>', '<input checked="checked">')
  275. self.assertHTMLEqual('<p>Hello', '<p> Hello')
  276. self.assertHTMLEqual('<p>Hello</p>World', '<p>Hello</p> World')
  277. def test_ignore_comments(self):
  278. self.assertHTMLEqual(
  279. '<div>Hello<!-- this is a comment --> World!</div>',
  280. '<div>Hello World!</div>')
  281. def test_unequal_html(self):
  282. self.assertHTMLNotEqual('<p>Hello</p>', '<p>Hello!</p>')
  283. self.assertHTMLNotEqual('<p>foo&#20;bar</p>', '<p>foo&nbsp;bar</p>')
  284. self.assertHTMLNotEqual('<p>foo bar</p>', '<p>foo &nbsp;bar</p>')
  285. self.assertHTMLNotEqual('<p>foo nbsp</p>', '<p>foo &nbsp;</p>')
  286. self.assertHTMLNotEqual('<p>foo #20</p>', '<p>foo &#20;</p>')
  287. self.assertHTMLNotEqual(
  288. '<p><span>Hello</span><span>World</span></p>',
  289. '<p><span>Hello</span>World</p>')
  290. self.assertHTMLNotEqual(
  291. '<p><span>Hello</span>World</p>',
  292. '<p><span>Hello</span><span>World</span></p>')
  293. def test_attributes(self):
  294. self.assertHTMLEqual(
  295. '<input type="text" id="id_name" />',
  296. '<input id="id_name" type="text" />')
  297. self.assertHTMLEqual(
  298. '''<input type='text' id="id_name" />''',
  299. '<input id="id_name" type="text" />')
  300. self.assertHTMLNotEqual(
  301. '<input type="text" id="id_name" />',
  302. '<input type="password" id="id_name" />')
  303. def test_complex_examples(self):
  304. self.assertHTMLEqual(
  305. """<tr><th><label for="id_first_name">First name:</label></th>
  306. <td><input type="text" name="first_name" value="John" id="id_first_name" /></td></tr>
  307. <tr><th><label for="id_last_name">Last name:</label></th>
  308. <td><input type="text" id="id_last_name" name="last_name" value="Lennon" /></td></tr>
  309. <tr><th><label for="id_birthday">Birthday:</label></th>
  310. <td><input type="text" value="1940-10-9" name="birthday" id="id_birthday" /></td></tr>""",
  311. """
  312. <tr><th>
  313. <label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" value="John" id="id_first_name" />
  314. </td></tr>
  315. <tr><th>
  316. <label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" value="Lennon" id="id_last_name" />
  317. </td></tr>
  318. <tr><th>
  319. <label for="id_birthday">Birthday:</label></th><td><input type="text" name="birthday" value="1940-10-9" id="id_birthday" />
  320. </td></tr>
  321. """)
  322. self.assertHTMLEqual(
  323. """<!DOCTYPE html>
  324. <html>
  325. <head>
  326. <link rel="stylesheet">
  327. <title>Document</title>
  328. <meta attribute="value">
  329. </head>
  330. <body>
  331. <p>
  332. This is a valid paragraph
  333. <div> this is a div AFTER the p</div>
  334. </body>
  335. </html>""", """
  336. <html>
  337. <head>
  338. <link rel="stylesheet">
  339. <title>Document</title>
  340. <meta attribute="value">
  341. </head>
  342. <body>
  343. <p> This is a valid paragraph
  344. <!-- browsers would close the p tag here -->
  345. <div> this is a div AFTER the p</div>
  346. </p> <!-- this is invalid HTML parsing, but it should make no
  347. difference in most cases -->
  348. </body>
  349. </html>""")
  350. def test_html_contain(self):
  351. # equal html contains each other
  352. dom1 = parse_html('<p>foo')
  353. dom2 = parse_html('<p>foo</p>')
  354. self.assertTrue(dom1 in dom2)
  355. self.assertTrue(dom2 in dom1)
  356. dom2 = parse_html('<div><p>foo</p></div>')
  357. self.assertTrue(dom1 in dom2)
  358. self.assertTrue(dom2 not in dom1)
  359. self.assertFalse('<p>foo</p>' in dom2)
  360. self.assertTrue('foo' in dom2)
  361. # when a root element is used ...
  362. dom1 = parse_html('<p>foo</p><p>bar</p>')
  363. dom2 = parse_html('<p>foo</p><p>bar</p>')
  364. self.assertTrue(dom1 in dom2)
  365. dom1 = parse_html('<p>foo</p>')
  366. self.assertTrue(dom1 in dom2)
  367. dom1 = parse_html('<p>bar</p>')
  368. self.assertTrue(dom1 in dom2)
  369. def test_count(self):
  370. # equal html contains each other one time
  371. dom1 = parse_html('<p>foo')
  372. dom2 = parse_html('<p>foo</p>')
  373. self.assertEqual(dom1.count(dom2), 1)
  374. self.assertEqual(dom2.count(dom1), 1)
  375. dom2 = parse_html('<p>foo</p><p>bar</p>')
  376. self.assertEqual(dom2.count(dom1), 1)
  377. dom2 = parse_html('<p>foo foo</p><p>foo</p>')
  378. self.assertEqual(dom2.count('foo'), 3)
  379. dom2 = parse_html('<p class="bar">foo</p>')
  380. self.assertEqual(dom2.count('bar'), 0)
  381. self.assertEqual(dom2.count('class'), 0)
  382. self.assertEqual(dom2.count('p'), 0)
  383. self.assertEqual(dom2.count('o'), 2)
  384. dom2 = parse_html('<p>foo</p><p>foo</p>')
  385. self.assertEqual(dom2.count(dom1), 2)
  386. dom2 = parse_html('<div><p>foo<input type=""></p><p>foo</p></div>')
  387. self.assertEqual(dom2.count(dom1), 1)
  388. dom2 = parse_html('<div><div><p>foo</p></div></div>')
  389. self.assertEqual(dom2.count(dom1), 1)
  390. dom2 = parse_html('<p>foo<p>foo</p></p>')
  391. self.assertEqual(dom2.count(dom1), 1)
  392. dom2 = parse_html('<p>foo<p>bar</p></p>')
  393. self.assertEqual(dom2.count(dom1), 0)
  394. def test_parsing_errors(self):
  395. with self.assertRaises(AssertionError):
  396. self.assertHTMLEqual('<p>', '')
  397. with self.assertRaises(AssertionError):
  398. self.assertHTMLEqual('', '<p>')
  399. with self.assertRaises(HTMLParseError):
  400. parse_html('</p>')
  401. def test_contains_html(self):
  402. response = HttpResponse('''<body>
  403. This is a form: <form action="" method="get">
  404. <input type="text" name="Hello" />
  405. </form></body>''')
  406. self.assertNotContains(response, "<input name='Hello' type='text'>")
  407. self.assertContains(response, '<form action="" method="get">')
  408. self.assertContains(response, "<input name='Hello' type='text'>", html=True)
  409. self.assertNotContains(response, '<form action="" method="get">', html=True)
  410. invalid_response = HttpResponse('''<body <bad>>''')
  411. with self.assertRaises(AssertionError):
  412. self.assertContains(invalid_response, '<p></p>')
  413. with self.assertRaises(AssertionError):
  414. self.assertContains(response, '<p "whats" that>')
  415. def test_unicode_handling(self):
  416. response = HttpResponse('<p class="help">Some help text for the title (with unicode ŠĐĆŽćžšđ)</p>')
  417. self.assertContains(response, '<p class="help">Some help text for the title (with unicode ŠĐĆŽćžšđ)</p>', html=True)
  418. class XMLEqualTests(TestCase):
  419. def test_simple_equal(self):
  420. xml1 = "<elem attr1='a' attr2='b' />"
  421. xml2 = "<elem attr1='a' attr2='b' />"
  422. self.assertXMLEqual(xml1, xml2)
  423. def test_simple_equal_unordered(self):
  424. xml1 = "<elem attr1='a' attr2='b' />"
  425. xml2 = "<elem attr2='b' attr1='a' />"
  426. self.assertXMLEqual(xml1, xml2)
  427. def test_simple_equal_raise(self):
  428. xml1 = "<elem attr1='a' />"
  429. xml2 = "<elem attr2='b' attr1='a' />"
  430. with self.assertRaises(AssertionError):
  431. self.assertXMLEqual(xml1, xml2)
  432. def test_simple_not_equal(self):
  433. xml1 = "<elem attr1='a' attr2='c' />"
  434. xml2 = "<elem attr1='a' attr2='b' />"
  435. self.assertXMLNotEqual(xml1, xml2)
  436. def test_simple_not_equal_raise(self):
  437. xml1 = "<elem attr1='a' attr2='b' />"
  438. xml2 = "<elem attr2='b' attr1='a' />"
  439. with self.assertRaises(AssertionError):
  440. self.assertXMLNotEqual(xml1, xml2)
  441. def test_parsing_errors(self):
  442. xml_unvalid = "<elem attr1='a attr2='b' />"
  443. xml2 = "<elem attr2='b' attr1='a' />"
  444. with self.assertRaises(AssertionError):
  445. self.assertXMLNotEqual(xml_unvalid, xml2)
  446. def test_comment_root(self):
  447. xml1 = "<?xml version='1.0'?><!-- comment1 --><elem attr1='a' attr2='b' />"
  448. xml2 = "<?xml version='1.0'?><!-- comment2 --><elem attr2='b' attr1='a' />"
  449. self.assertXMLEqual(xml1, xml2)
  450. class SkippingExtraTests(TestCase):
  451. fixtures = ['should_not_be_loaded.json']
  452. # HACK: This depends on internals of our TestCase subclasses
  453. def __call__(self, result=None):
  454. # Detect fixture loading by counting SQL queries, should be zero
  455. with self.assertNumQueries(0):
  456. super(SkippingExtraTests, self).__call__(result)
  457. @skip("Fixture loading should not be performed for skipped tests.")
  458. def test_fixtures_are_skipped(self):
  459. pass
  460. class AssertRaisesMsgTest(SimpleTestCase):
  461. def test_special_re_chars(self):
  462. """assertRaisesMessage shouldn't interpret RE special chars."""
  463. def func1():
  464. raise ValueError("[.*x+]y?")
  465. self.assertRaisesMessage(ValueError, "[.*x+]y?", func1)
  466. class AssertFieldOutputTests(SimpleTestCase):
  467. def test_assert_field_output(self):
  468. error_invalid = ['Enter a valid email address.']
  469. self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid})
  470. self.assertRaises(AssertionError, self.assertFieldOutput, EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid + ['Another error']})
  471. self.assertRaises(AssertionError, self.assertFieldOutput, EmailField, {'a@a.com': 'Wrong output'}, {'aaa': error_invalid})
  472. self.assertRaises(AssertionError, self.assertFieldOutput, EmailField, {'a@a.com': 'a@a.com'}, {'aaa': ['Come on, gimme some well formatted data, dude.']})
  473. def test_custom_required_message(self):
  474. class MyCustomField(IntegerField):
  475. default_error_messages = {
  476. 'required': 'This is really required.',
  477. }
  478. self.assertFieldOutput(MyCustomField, {}, {}, empty_value=None)
  479. class DoctestNormalizerTest(IgnoreDeprecationWarningsMixin, SimpleTestCase):
  480. def test_normalizer(self):
  481. from django.test.simple import make_doctest
  482. suite = make_doctest("test_utils.doctest_output")
  483. failures = unittest.TextTestRunner(stream=six.StringIO()).run(suite)
  484. self.assertEqual(failures.failures, [])