tests.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. from __future__ import with_statement
  2. from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
  3. from django.utils.unittest import skip
  4. from models import Person
  5. class SkippingTestCase(TestCase):
  6. def test_skip_unless_db_feature(self):
  7. "A test that might be skipped is actually called."
  8. # Total hack, but it works, just want an attribute that's always true.
  9. @skipUnlessDBFeature("__class__")
  10. def test_func():
  11. raise ValueError
  12. self.assertRaises(ValueError, test_func)
  13. class AssertNumQueriesTests(TestCase):
  14. urls = 'regressiontests.test_utils.urls'
  15. def test_assert_num_queries(self):
  16. def test_func():
  17. raise ValueError
  18. self.assertRaises(ValueError,
  19. self.assertNumQueries, 2, test_func
  20. )
  21. def test_assert_num_queries_with_client(self):
  22. person = Person.objects.create(name='test')
  23. self.assertNumQueries(
  24. 1,
  25. self.client.get,
  26. "/test_utils/get_person/%s/" % person.pk
  27. )
  28. self.assertNumQueries(
  29. 1,
  30. self.client.get,
  31. "/test_utils/get_person/%s/" % person.pk
  32. )
  33. def test_func():
  34. self.client.get("/test_utils/get_person/%s/" % person.pk)
  35. self.client.get("/test_utils/get_person/%s/" % person.pk)
  36. self.assertNumQueries(2, test_func)
  37. class AssertNumQueriesContextManagerTests(TestCase):
  38. urls = 'regressiontests.test_utils.urls'
  39. def test_simple(self):
  40. with self.assertNumQueries(0):
  41. pass
  42. with self.assertNumQueries(1):
  43. Person.objects.count()
  44. with self.assertNumQueries(2):
  45. Person.objects.count()
  46. Person.objects.count()
  47. def test_failure(self):
  48. with self.assertRaises(AssertionError) as exc_info:
  49. with self.assertNumQueries(2):
  50. Person.objects.count()
  51. self.assertIn("1 queries executed, 2 expected", str(exc_info.exception))
  52. with self.assertRaises(TypeError):
  53. with self.assertNumQueries(4000):
  54. raise TypeError
  55. def test_with_client(self):
  56. person = Person.objects.create(name="test")
  57. with self.assertNumQueries(1):
  58. self.client.get("/test_utils/get_person/%s/" % person.pk)
  59. with self.assertNumQueries(1):
  60. self.client.get("/test_utils/get_person/%s/" % person.pk)
  61. with self.assertNumQueries(2):
  62. self.client.get("/test_utils/get_person/%s/" % person.pk)
  63. self.client.get("/test_utils/get_person/%s/" % person.pk)
  64. class SaveRestoreWarningState(TestCase):
  65. def test_save_restore_warnings_state(self):
  66. """
  67. Ensure save_warnings_state/restore_warnings_state work correctly.
  68. """
  69. # In reality this test could be satisfied by many broken implementations
  70. # of save_warnings_state/restore_warnings_state (e.g. just
  71. # warnings.resetwarnings()) , but it is difficult to test more.
  72. import warnings
  73. self.save_warnings_state()
  74. class MyWarning(Warning):
  75. pass
  76. # Add a filter that causes an exception to be thrown, so we can catch it
  77. warnings.simplefilter("error", MyWarning)
  78. self.assertRaises(Warning, lambda: warnings.warn("warn", MyWarning))
  79. # Now restore.
  80. self.restore_warnings_state()
  81. # After restoring, we shouldn't get an exception. But we don't want a
  82. # warning printed either, so we have to silence the warning.
  83. warnings.simplefilter("ignore", MyWarning)
  84. warnings.warn("warn", MyWarning)
  85. # Remove the filter we just added.
  86. self.restore_warnings_state()
  87. class SkippingExtraTests(TestCase):
  88. fixtures = ['should_not_be_loaded.json']
  89. # HACK: This depends on internals of our TestCase subclasses
  90. def __call__(self, result=None):
  91. # Detect fixture loading by counting SQL queries, should be zero
  92. with self.assertNumQueries(0):
  93. super(SkippingExtraTests, self).__call__(result)
  94. @skip("Fixture loading should not be performed for skipped tests.")
  95. def test_fixtures_are_skipped(self):
  96. pass
  97. class AssertRaisesMsgTest(SimpleTestCase):
  98. def test_special_re_chars(self):
  99. """assertRaisesMessage shouldn't interpret RE special chars."""
  100. def func1():
  101. raise ValueError("[.*x+]y?")
  102. self.assertRaisesMessage(ValueError, "[.*x+]y?", func1)
  103. __test__ = {"API_TEST": r"""
  104. # Some checks of the doctest output normalizer.
  105. # Standard doctests do fairly
  106. >>> from django.utils import simplejson
  107. >>> from django.utils.xmlutils import SimplerXMLGenerator
  108. >>> from StringIO import StringIO
  109. >>> def produce_long():
  110. ... return 42L
  111. >>> def produce_int():
  112. ... return 42
  113. >>> def produce_json():
  114. ... return simplejson.dumps(['foo', {'bar': ('baz', None, 1.0, 2), 'whiz': 42}])
  115. >>> def produce_xml():
  116. ... stream = StringIO()
  117. ... xml = SimplerXMLGenerator(stream, encoding='utf-8')
  118. ... xml.startDocument()
  119. ... xml.startElement("foo", {"aaa" : "1.0", "bbb": "2.0"})
  120. ... xml.startElement("bar", {"ccc" : "3.0"})
  121. ... xml.characters("Hello")
  122. ... xml.endElement("bar")
  123. ... xml.startElement("whiz", {})
  124. ... xml.characters("Goodbye")
  125. ... xml.endElement("whiz")
  126. ... xml.endElement("foo")
  127. ... xml.endDocument()
  128. ... return stream.getvalue()
  129. >>> def produce_xml_fragment():
  130. ... stream = StringIO()
  131. ... xml = SimplerXMLGenerator(stream, encoding='utf-8')
  132. ... xml.startElement("foo", {"aaa": "1.0", "bbb": "2.0"})
  133. ... xml.characters("Hello")
  134. ... xml.endElement("foo")
  135. ... xml.startElement("bar", {"ccc": "3.0", "ddd": "4.0"})
  136. ... xml.endElement("bar")
  137. ... return stream.getvalue()
  138. # Long values are normalized and are comparable to normal integers ...
  139. >>> produce_long()
  140. 42
  141. # ... and vice versa
  142. >>> produce_int()
  143. 42L
  144. # JSON output is normalized for field order, so it doesn't matter
  145. # which order json dictionary attributes are listed in output
  146. >>> produce_json()
  147. '["foo", {"bar": ["baz", null, 1.0, 2], "whiz": 42}]'
  148. >>> produce_json()
  149. '["foo", {"whiz": 42, "bar": ["baz", null, 1.0, 2]}]'
  150. # XML output is normalized for attribute order, so it doesn't matter
  151. # which order XML element attributes are listed in output
  152. >>> produce_xml()
  153. '<?xml version="1.0" encoding="UTF-8"?>\n<foo aaa="1.0" bbb="2.0"><bar ccc="3.0">Hello</bar><whiz>Goodbye</whiz></foo>'
  154. >>> produce_xml()
  155. '<?xml version="1.0" encoding="UTF-8"?>\n<foo bbb="2.0" aaa="1.0"><bar ccc="3.0">Hello</bar><whiz>Goodbye</whiz></foo>'
  156. >>> produce_xml_fragment()
  157. '<foo aaa="1.0" bbb="2.0">Hello</foo><bar ccc="3.0" ddd="4.0"></bar>'
  158. >>> produce_xml_fragment()
  159. '<foo bbb="2.0" aaa="1.0">Hello</foo><bar ddd="4.0" ccc="3.0"></bar>'
  160. """}