You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_compat.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. # -*- coding: utf-8 -*-
  2. import codecs
  3. import datetime
  4. import os
  5. from tempfile import NamedTemporaryFile
  6. from django.utils import six
  7. from django.utils.encoding import smart_text
  8. from django.utils.six.moves import cStringIO
  9. from django.test import TestCase, override_settings
  10. from oscar.core.compat import UnicodeCSVWriter, existing_user_fields
  11. class unicodeobj(object):
  12. def __init__(self, s):
  13. self.s = s
  14. def __str__(self):
  15. return self.s
  16. def __unicode__(self):
  17. return self.s
  18. class TestExistingUserFields(TestCase):
  19. def test_order(self):
  20. fields = existing_user_fields(['email', 'first_name', 'last_name'])
  21. self.assertEqual(fields, ['email', 'first_name', 'last_name'])
  22. class TestUnicodeCSVWriter(TestCase):
  23. def test_can_write_different_values(self):
  24. writer = UnicodeCSVWriter(open_file=cStringIO())
  25. s = u'ünįcodē'
  26. rows = [[s, unicodeobj(s), 123, datetime.date.today()], ]
  27. writer.writerows(rows)
  28. self.assertRaises(TypeError, writer.writerows, [object()])
  29. def test_context_manager(self):
  30. tmp_file = NamedTemporaryFile()
  31. with UnicodeCSVWriter(filename=tmp_file.name) as writer:
  32. s = u'ünįcodē'
  33. rows = [[s, unicodeobj(s), 123, datetime.date.today()], ]
  34. writer.writerows(rows)
  35. def test_csv_write_output(self):
  36. tmp_file = NamedTemporaryFile(delete=False)
  37. with UnicodeCSVWriter(filename=tmp_file.name) as writer:
  38. s = u'ünįcodē'
  39. row = [s, 123, 'foo-bar']
  40. writer.writerows([row])
  41. with open(tmp_file.name, 'r') as read_file:
  42. content = smart_text(read_file.read(), encoding='utf-8').strip()
  43. self.assertEqual(content, u'ünįcodē,123,foo-bar')
  44. # Clean up
  45. os.unlink(tmp_file.name)
  46. @override_settings(OSCAR_CSV_INCLUDE_BOM=True)
  47. def test_bom_write_with_open_file(self):
  48. csv_file = NamedTemporaryFile(delete=False)
  49. with open(csv_file.name, 'w') as open_file:
  50. writer = UnicodeCSVWriter(open_file=open_file, encoding="utf-8")
  51. s = u'ünįcodē'
  52. row = [s, 123, datetime.date.today()]
  53. writer.writerows([row])
  54. with open(csv_file.name, 'rb') as read_file:
  55. self.assertTrue(read_file.read().startswith(codecs.BOM_UTF8))
  56. # Clean up
  57. os.unlink(csv_file.name)
  58. @override_settings(OSCAR_CSV_INCLUDE_BOM=True)
  59. def test_bom_write_with_filename(self):
  60. csv_file = NamedTemporaryFile(delete=False)
  61. with UnicodeCSVWriter(filename=csv_file.name, encoding="utf-8") as writer:
  62. s = u'ünįcodē'
  63. row = [s, 123, datetime.date.today()]
  64. writer.writerows([row])
  65. with open(csv_file.name, 'rb') as read_file:
  66. self.assertTrue(read_file.read().startswith(codecs.BOM_UTF8))
  67. # Clean up
  68. os.unlink(csv_file.name)
  69. @override_settings(OSCAR_CSV_INCLUDE_BOM=True)
  70. def test_bom_not_written_for_other_encodings(self):
  71. csv_file = NamedTemporaryFile(delete=False)
  72. with UnicodeCSVWriter(filename=csv_file.name, encoding="ascii") as writer:
  73. s = 'boring ascii'
  74. row = [s, 123, datetime.date.today()]
  75. writer.writerows([row])
  76. with open(csv_file.name, 'rb') as read_file:
  77. self.assertFalse(read_file.read().startswith(codecs.BOM_UTF8))
  78. # Clean up
  79. os.unlink(csv_file.name)
  80. class TestPython3Compatibility(TestCase):
  81. def test_models_define_python_3_compatible_representation(self):
  82. """
  83. In Python 2, models can define __unicode__ to get a text representation,
  84. in Python 3 this is achieved by defining __str__. The
  85. python_2_unicode_compatible decorator helps with that. We must use it
  86. every time we define a text representation; this test checks that it's
  87. used correctly.
  88. """
  89. from django.apps import apps
  90. models = [
  91. model for model in apps.get_models() if 'oscar' in repr(model)]
  92. invalid_models = []
  93. for model in models:
  94. # Use abstract model if it exists
  95. if 'oscar' in repr(model.__base__):
  96. model = model.__base__
  97. dict_ = model.__dict__
  98. if '__str__' in dict_:
  99. if six.PY2:
  100. valid = '__unicode__' in dict_
  101. else:
  102. valid = '__unicode__' not in dict_
  103. else:
  104. valid = '__unicode__' not in dict_
  105. if not valid:
  106. invalid_models.append(model)
  107. if invalid_models:
  108. self.fail(
  109. "Those models don't use the python_2_compatible decorator or define __unicode__: %s" % invalid_models)