PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/django/branches/attic/queryset-refactor/tests/regressiontests/serializers_regress/tests.py

https://bitbucket.org/mirror/django/
Python | 345 lines | 308 code | 18 blank | 19 comment | 5 complexity | 8ab562a0412df1c78638e25bd62fc398 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. """
  2. A test spanning all the capabilities of all the serializers.
  3. This class defines sample data and a dynamically generated
  4. test case that is capable of testing the capabilities of
  5. the serializers. This includes all valid data values, plus
  6. forward, backwards and self references.
  7. """
  8. import unittest, datetime
  9. from cStringIO import StringIO
  10. from django.utils.functional import curry
  11. from django.core import serializers
  12. from django.db import transaction
  13. from django.core import management
  14. from django.conf import settings
  15. from models import *
  16. try:
  17. import decimal
  18. except ImportError:
  19. from django.utils import _decimal as decimal
  20. # A set of functions that can be used to recreate
  21. # test data objects of various kinds.
  22. # The save method is a raw base model save, to make
  23. # sure that the data in the database matches the
  24. # exact test case.
  25. def data_create(pk, klass, data):
  26. instance = klass(id=pk)
  27. instance.data = data
  28. models.Model.save_base(instance, raw=True)
  29. return instance
  30. def generic_create(pk, klass, data):
  31. instance = klass(id=pk)
  32. instance.data = data[0]
  33. models.Model.save_base(instance, raw=True)
  34. for tag in data[1:]:
  35. instance.tags.create(data=tag)
  36. return instance
  37. def fk_create(pk, klass, data):
  38. instance = klass(id=pk)
  39. setattr(instance, 'data_id', data)
  40. models.Model.save_base(instance, raw=True)
  41. return instance
  42. def m2m_create(pk, klass, data):
  43. instance = klass(id=pk)
  44. models.Model.save_base(instance, raw=True)
  45. instance.data = data
  46. return instance
  47. def o2o_create(pk, klass, data):
  48. instance = klass()
  49. instance.data_id = data
  50. models.Model.save_base(instance, raw=True)
  51. return instance
  52. def pk_create(pk, klass, data):
  53. instance = klass()
  54. instance.data = data
  55. models.Model.save_base(instance, raw=True)
  56. return instance
  57. # A set of functions that can be used to compare
  58. # test data objects of various kinds
  59. def data_compare(testcase, pk, klass, data):
  60. instance = klass.objects.get(id=pk)
  61. testcase.assertEqual(data, instance.data,
  62. "Objects with PK=%d not equal; expected '%s' (%s), got '%s' (%s)" % (pk,data, type(data), instance.data, type(instance.data)))
  63. def generic_compare(testcase, pk, klass, data):
  64. instance = klass.objects.get(id=pk)
  65. testcase.assertEqual(data[0], instance.data)
  66. testcase.assertEqual(data[1:], [t.data for t in instance.tags.all()])
  67. def fk_compare(testcase, pk, klass, data):
  68. instance = klass.objects.get(id=pk)
  69. testcase.assertEqual(data, instance.data_id)
  70. def m2m_compare(testcase, pk, klass, data):
  71. instance = klass.objects.get(id=pk)
  72. testcase.assertEqual(data, [obj.id for obj in instance.data.all()])
  73. def o2o_compare(testcase, pk, klass, data):
  74. instance = klass.objects.get(data=data)
  75. testcase.assertEqual(data, instance.data_id)
  76. def pk_compare(testcase, pk, klass, data):
  77. instance = klass.objects.get(data=data)
  78. testcase.assertEqual(data, instance.data)
  79. # Define some data types. Each data type is
  80. # actually a pair of functions; one to create
  81. # and one to compare objects of that type
  82. data_obj = (data_create, data_compare)
  83. generic_obj = (generic_create, generic_compare)
  84. fk_obj = (fk_create, fk_compare)
  85. m2m_obj = (m2m_create, m2m_compare)
  86. o2o_obj = (o2o_create, o2o_compare)
  87. pk_obj = (pk_create, pk_compare)
  88. test_data = [
  89. # Format: (data type, PK value, Model Class, data)
  90. (data_obj, 1, BooleanData, True),
  91. (data_obj, 2, BooleanData, False),
  92. (data_obj, 10, CharData, "Test Char Data"),
  93. (data_obj, 11, CharData, ""),
  94. (data_obj, 12, CharData, "None"),
  95. (data_obj, 13, CharData, "null"),
  96. (data_obj, 14, CharData, "NULL"),
  97. (data_obj, 15, CharData, None),
  98. # (We use something that will fit into a latin1 database encoding here,
  99. # because that is still the default used on many system setups.)
  100. (data_obj, 16, CharData, u'\xa5'),
  101. (data_obj, 20, DateData, datetime.date(2006,6,16)),
  102. (data_obj, 21, DateData, None),
  103. (data_obj, 30, DateTimeData, datetime.datetime(2006,6,16,10,42,37)),
  104. (data_obj, 31, DateTimeData, None),
  105. (data_obj, 40, EmailData, "hovercraft@example.com"),
  106. (data_obj, 41, EmailData, None),
  107. (data_obj, 42, EmailData, ""),
  108. (data_obj, 50, FileData, 'file:///foo/bar/whiz.txt'),
  109. (data_obj, 51, FileData, None),
  110. (data_obj, 52, FileData, ""),
  111. (data_obj, 60, FilePathData, "/foo/bar/whiz.txt"),
  112. (data_obj, 61, FilePathData, None),
  113. (data_obj, 62, FilePathData, ""),
  114. (data_obj, 70, DecimalData, decimal.Decimal('12.345')),
  115. (data_obj, 71, DecimalData, decimal.Decimal('-12.345')),
  116. (data_obj, 72, DecimalData, decimal.Decimal('0.0')),
  117. (data_obj, 73, DecimalData, None),
  118. (data_obj, 74, FloatData, 12.345),
  119. (data_obj, 75, FloatData, -12.345),
  120. (data_obj, 76, FloatData, 0.0),
  121. (data_obj, 77, FloatData, None),
  122. (data_obj, 80, IntegerData, 123456789),
  123. (data_obj, 81, IntegerData, -123456789),
  124. (data_obj, 82, IntegerData, 0),
  125. (data_obj, 83, IntegerData, None),
  126. #(XX, ImageData
  127. (data_obj, 90, IPAddressData, "127.0.0.1"),
  128. (data_obj, 91, IPAddressData, None),
  129. (data_obj, 100, NullBooleanData, True),
  130. (data_obj, 101, NullBooleanData, False),
  131. (data_obj, 102, NullBooleanData, None),
  132. (data_obj, 110, PhoneData, "212-634-5789"),
  133. (data_obj, 111, PhoneData, None),
  134. (data_obj, 120, PositiveIntegerData, 123456789),
  135. (data_obj, 121, PositiveIntegerData, None),
  136. (data_obj, 130, PositiveSmallIntegerData, 12),
  137. (data_obj, 131, PositiveSmallIntegerData, None),
  138. (data_obj, 140, SlugData, "this-is-a-slug"),
  139. (data_obj, 141, SlugData, None),
  140. (data_obj, 142, SlugData, ""),
  141. (data_obj, 150, SmallData, 12),
  142. (data_obj, 151, SmallData, -12),
  143. (data_obj, 152, SmallData, 0),
  144. (data_obj, 153, SmallData, None),
  145. (data_obj, 160, TextData, """This is a long piece of text.
  146. It contains line breaks.
  147. Several of them.
  148. The end."""),
  149. (data_obj, 161, TextData, ""),
  150. (data_obj, 162, TextData, None),
  151. (data_obj, 170, TimeData, datetime.time(10,42,37)),
  152. (data_obj, 171, TimeData, None),
  153. (data_obj, 180, USStateData, "MA"),
  154. (data_obj, 181, USStateData, None),
  155. (data_obj, 182, USStateData, ""),
  156. (data_obj, 190, XMLData, "<foo></foo>"),
  157. (data_obj, 191, XMLData, None),
  158. (data_obj, 192, XMLData, ""),
  159. (generic_obj, 200, GenericData, ['Generic Object 1', 'tag1', 'tag2']),
  160. (generic_obj, 201, GenericData, ['Generic Object 2', 'tag2', 'tag3']),
  161. (data_obj, 300, Anchor, "Anchor 1"),
  162. (data_obj, 301, Anchor, "Anchor 2"),
  163. (data_obj, 302, UniqueAnchor, "UAnchor 1"),
  164. (fk_obj, 400, FKData, 300), # Post reference
  165. (fk_obj, 401, FKData, 500), # Pre reference
  166. (fk_obj, 402, FKData, None), # Empty reference
  167. (m2m_obj, 410, M2MData, []), # Empty set
  168. (m2m_obj, 411, M2MData, [300,301]), # Post reference
  169. (m2m_obj, 412, M2MData, [500,501]), # Pre reference
  170. (m2m_obj, 413, M2MData, [300,301,500,501]), # Pre and Post reference
  171. (o2o_obj, None, O2OData, 300), # Post reference
  172. (o2o_obj, None, O2OData, 500), # Pre reference
  173. (fk_obj, 430, FKSelfData, 431), # Pre reference
  174. (fk_obj, 431, FKSelfData, 430), # Post reference
  175. (fk_obj, 432, FKSelfData, None), # Empty reference
  176. (m2m_obj, 440, M2MSelfData, []),
  177. (m2m_obj, 441, M2MSelfData, []),
  178. (m2m_obj, 442, M2MSelfData, [440, 441]),
  179. (m2m_obj, 443, M2MSelfData, [445, 446]),
  180. (m2m_obj, 444, M2MSelfData, [440, 441, 445, 446]),
  181. (m2m_obj, 445, M2MSelfData, []),
  182. (m2m_obj, 446, M2MSelfData, []),
  183. (fk_obj, 450, FKDataToField, "UAnchor 1"),
  184. (fk_obj, 451, FKDataToField, "UAnchor 2"),
  185. (fk_obj, 452, FKDataToField, None),
  186. (fk_obj, 460, FKDataToO2O, 300),
  187. (data_obj, 500, Anchor, "Anchor 3"),
  188. (data_obj, 501, Anchor, "Anchor 4"),
  189. (data_obj, 502, UniqueAnchor, "UAnchor 2"),
  190. (pk_obj, 601, BooleanPKData, True),
  191. (pk_obj, 602, BooleanPKData, False),
  192. (pk_obj, 610, CharPKData, "Test Char PKData"),
  193. # (pk_obj, 620, DatePKData, datetime.date(2006,6,16)),
  194. # (pk_obj, 630, DateTimePKData, datetime.datetime(2006,6,16,10,42,37)),
  195. (pk_obj, 640, EmailPKData, "hovercraft@example.com"),
  196. (pk_obj, 650, FilePKData, 'file:///foo/bar/whiz.txt'),
  197. (pk_obj, 660, FilePathPKData, "/foo/bar/whiz.txt"),
  198. (pk_obj, 670, DecimalPKData, decimal.Decimal('12.345')),
  199. (pk_obj, 671, DecimalPKData, decimal.Decimal('-12.345')),
  200. (pk_obj, 672, DecimalPKData, decimal.Decimal('0.0')),
  201. (pk_obj, 673, FloatPKData, 12.345),
  202. (pk_obj, 674, FloatPKData, -12.345),
  203. (pk_obj, 675, FloatPKData, 0.0),
  204. (pk_obj, 680, IntegerPKData, 123456789),
  205. (pk_obj, 681, IntegerPKData, -123456789),
  206. (pk_obj, 682, IntegerPKData, 0),
  207. # (XX, ImagePKData
  208. (pk_obj, 690, IPAddressPKData, "127.0.0.1"),
  209. # (pk_obj, 700, NullBooleanPKData, True),
  210. # (pk_obj, 701, NullBooleanPKData, False),
  211. (pk_obj, 710, PhonePKData, "212-634-5789"),
  212. (pk_obj, 720, PositiveIntegerPKData, 123456789),
  213. (pk_obj, 730, PositiveSmallIntegerPKData, 12),
  214. (pk_obj, 740, SlugPKData, "this-is-a-slug"),
  215. (pk_obj, 750, SmallPKData, 12),
  216. (pk_obj, 751, SmallPKData, -12),
  217. (pk_obj, 752, SmallPKData, 0),
  218. # (pk_obj, 760, TextPKData, """This is a long piece of text.
  219. # It contains line breaks.
  220. # Several of them.
  221. # The end."""),
  222. # (pk_obj, 770, TimePKData, datetime.time(10,42,37)),
  223. (pk_obj, 780, USStatePKData, "MA"),
  224. # (pk_obj, 790, XMLPKData, "<foo></foo>"),
  225. (data_obj, 800, AutoNowDateTimeData, datetime.datetime(2006,6,16,10,42,37)),
  226. (data_obj, 810, ModifyingSaveData, 42),
  227. ]
  228. # Because Oracle treats the empty string as NULL, Oracle is expected to fail
  229. # when field.empty_strings_allowed is True and the value is None; skip these
  230. # tests.
  231. if settings.DATABASE_ENGINE == 'oracle':
  232. test_data = [data for data in test_data
  233. if not (data[0] == data_obj and
  234. data[2]._meta.get_field('data').empty_strings_allowed and
  235. data[3] is None)]
  236. # Dynamically create serializer tests to ensure that all
  237. # registered serializers are automatically tested.
  238. class SerializerTests(unittest.TestCase):
  239. pass
  240. def serializerTest(format, self):
  241. # Clear the database first
  242. management.call_command('flush', verbosity=0, interactive=False)
  243. # Create all the objects defined in the test data
  244. objects = []
  245. transaction.enter_transaction_management()
  246. transaction.managed(True)
  247. for (func, pk, klass, datum) in test_data:
  248. objects.append(func[0](pk, klass, datum))
  249. transaction.commit()
  250. transaction.leave_transaction_management()
  251. # Add the generic tagged objects to the object list
  252. objects.extend(Tag.objects.all())
  253. # Serialize the test database
  254. serialized_data = serializers.serialize(format, objects, indent=2)
  255. # Flush the database and recreate from the serialized data
  256. management.call_command('flush', verbosity=0, interactive=False)
  257. transaction.enter_transaction_management()
  258. transaction.managed(True)
  259. for obj in serializers.deserialize(format, serialized_data):
  260. obj.save()
  261. transaction.commit()
  262. transaction.leave_transaction_management()
  263. # Assert that the deserialized data is the same
  264. # as the original source
  265. for (func, pk, klass, datum) in test_data:
  266. func[1](self, pk, klass, datum)
  267. def fieldsTest(format, self):
  268. # Clear the database first
  269. management.call_command('flush', verbosity=0, interactive=False)
  270. obj = ComplexModel(field1='first',field2='second',field3='third')
  271. obj.save()
  272. # Serialize then deserialize the test database
  273. serialized_data = serializers.serialize(format, [obj], indent=2, fields=('field1','field3'))
  274. result = serializers.deserialize(format, serialized_data).next()
  275. # Check that the deserialized object contains data in only the serialized fields.
  276. self.assertEqual(result.object.field1, 'first')
  277. self.assertEqual(result.object.field2, '')
  278. self.assertEqual(result.object.field3, 'third')
  279. def streamTest(format, self):
  280. # Clear the database first
  281. management.call_command('flush', verbosity=0, interactive=False)
  282. obj = ComplexModel(field1='first',field2='second',field3='third')
  283. obj.save()
  284. # Serialize the test database to a stream
  285. stream = StringIO()
  286. serializers.serialize(format, [obj], indent=2, stream=stream)
  287. # Serialize normally for a comparison
  288. string_data = serializers.serialize(format, [obj], indent=2)
  289. # Check that the two are the same
  290. self.assertEqual(string_data, stream.getvalue())
  291. stream.close()
  292. for format in serializers.get_serializer_formats():
  293. setattr(SerializerTests, 'test_'+format+'_serializer', curry(serializerTest, format))
  294. setattr(SerializerTests, 'test_'+format+'_serializer_fields', curry(fieldsTest, format))
  295. if format != 'python':
  296. setattr(SerializerTests, 'test_'+format+'_serializer_stream', curry(streamTest, format))