tests.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. from __future__ import absolute_import
  2. import pickle
  3. import six
  4. from django.db import connection, models
  5. from django.db.models import F
  6. from django.test import TestCase
  7. from bitfield import Bit, BitField, BitHandler
  8. from bitfield.compat import bitand, bitor
  9. from .forms import BitFieldTestModelForm
  10. from .models import BitFieldTestModel
  11. class BitHandlerTest(TestCase):
  12. def test_comparison(self):
  13. bithandler_1 = BitHandler(0, ('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3'))
  14. bithandler_2 = BitHandler(1, ('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3'))
  15. bithandler_3 = BitHandler(0, ('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3'))
  16. assert bithandler_1 == bithandler_1
  17. assert bithandler_1 != bithandler_2
  18. assert bithandler_1 == bithandler_3
  19. def test_defaults(self):
  20. bithandler = BitHandler(0, ('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3'))
  21. # Default value of 0.
  22. self.assertEquals(int(bithandler), 0)
  23. # Test bit numbers.
  24. self.assertEquals(int(bithandler.FLAG_0.number), 0)
  25. self.assertEquals(int(bithandler.FLAG_1.number), 1)
  26. self.assertEquals(int(bithandler.FLAG_2.number), 2)
  27. self.assertEquals(int(bithandler.FLAG_3.number), 3)
  28. # Negative test non-existant key.
  29. self.assertRaises(AttributeError, lambda: bithandler.FLAG_4)
  30. # Test bool().
  31. self.assertEquals(bool(bithandler.FLAG_0), False)
  32. self.assertEquals(bool(bithandler.FLAG_1), False)
  33. self.assertEquals(bool(bithandler.FLAG_2), False)
  34. self.assertEquals(bool(bithandler.FLAG_3), False)
  35. def test_nonzero_default(self):
  36. bithandler = BitHandler(1, ('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3'))
  37. self.assertEquals(bool(bithandler.FLAG_0), True)
  38. self.assertEquals(bool(bithandler.FLAG_1), False)
  39. self.assertEquals(bool(bithandler.FLAG_2), False)
  40. self.assertEquals(bool(bithandler.FLAG_3), False)
  41. bithandler = BitHandler(2, ('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3'))
  42. self.assertEquals(bool(bithandler.FLAG_0), False)
  43. self.assertEquals(bool(bithandler.FLAG_1), True)
  44. self.assertEquals(bool(bithandler.FLAG_2), False)
  45. self.assertEquals(bool(bithandler.FLAG_3), False)
  46. bithandler = BitHandler(3, ('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3'))
  47. self.assertEquals(bool(bithandler.FLAG_0), True)
  48. self.assertEquals(bool(bithandler.FLAG_1), True)
  49. self.assertEquals(bool(bithandler.FLAG_2), False)
  50. self.assertEquals(bool(bithandler.FLAG_3), False)
  51. bithandler = BitHandler(4, ('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3'))
  52. self.assertEquals(bool(bithandler.FLAG_0), False)
  53. self.assertEquals(bool(bithandler.FLAG_1), False)
  54. self.assertEquals(bool(bithandler.FLAG_2), True)
  55. self.assertEquals(bool(bithandler.FLAG_3), False)
  56. def test_mutation(self):
  57. bithandler = BitHandler(0, ('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3'))
  58. self.assertEquals(bool(bithandler.FLAG_0), False)
  59. self.assertEquals(bool(bithandler.FLAG_1), False)
  60. self.assertEquals(bool(bithandler.FLAG_2), False)
  61. self.assertEquals(bool(bithandler.FLAG_3), False)
  62. bithandler = BitHandler(bithandler | 1, bithandler._keys)
  63. self.assertEquals(bool(bithandler.FLAG_0), True)
  64. self.assertEquals(bool(bithandler.FLAG_1), False)
  65. self.assertEquals(bool(bithandler.FLAG_2), False)
  66. self.assertEquals(bool(bithandler.FLAG_3), False)
  67. bithandler ^= 3
  68. self.assertEquals(int(bithandler), 2)
  69. self.assertEquals(bool(bithandler & 1), False)
  70. bithandler.FLAG_0 = False
  71. self.assertEquals(bithandler.FLAG_0, False)
  72. bithandler.FLAG_1 = True
  73. self.assertEquals(bithandler.FLAG_0, False)
  74. self.assertEquals(bithandler.FLAG_1, True)
  75. bithandler.FLAG_2 = False
  76. self.assertEquals(bithandler.FLAG_0, False)
  77. self.assertEquals(bithandler.FLAG_1, True)
  78. self.assertEquals(bithandler.FLAG_2, False)
  79. class BitTest(TestCase):
  80. def test_int(self):
  81. bit = Bit(0)
  82. self.assertEquals(int(bit), 1)
  83. self.assertEquals(bool(bit), True)
  84. self.assertFalse(not bit)
  85. def test_comparison(self):
  86. self.assertEquals(Bit(0), Bit(0))
  87. self.assertNotEquals(Bit(1), Bit(0))
  88. self.assertNotEquals(Bit(0, 0), Bit(0, 1))
  89. self.assertEquals(Bit(0, 1), Bit(0, 1))
  90. self.assertEquals(Bit(0), 1)
  91. def test_and(self):
  92. self.assertEquals(1 & Bit(2), 0)
  93. self.assertEquals(1 & Bit(0), 1)
  94. self.assertEquals(1 & ~Bit(0), 0)
  95. self.assertEquals(Bit(0) & Bit(2), 0)
  96. self.assertEquals(Bit(0) & Bit(0), 1)
  97. self.assertEquals(Bit(0) & ~Bit(0), 0)
  98. def test_or(self):
  99. self.assertEquals(1 | Bit(2), 5)
  100. self.assertEquals(1 | Bit(5), 33)
  101. self.assertEquals(1 | ~Bit(2), -5)
  102. self.assertEquals(Bit(0) | Bit(2), 5)
  103. self.assertEquals(Bit(0) | Bit(5), 33)
  104. self.assertEquals(Bit(0) | ~Bit(2), -5)
  105. def test_xor(self):
  106. self.assertEquals(1 ^ Bit(2), 5)
  107. self.assertEquals(1 ^ Bit(0), 0)
  108. self.assertEquals(1 ^ Bit(1), 3)
  109. self.assertEquals(1 ^ Bit(5), 33)
  110. self.assertEquals(1 ^ ~Bit(2), -6)
  111. self.assertEquals(Bit(0) ^ Bit(2), 5)
  112. self.assertEquals(Bit(0) ^ Bit(0), 0)
  113. self.assertEquals(Bit(0) ^ Bit(1), 3)
  114. self.assertEquals(Bit(0) ^ Bit(5), 33)
  115. self.assertEquals(Bit(0) ^ ~Bit(2), -6)
  116. class BitFieldTest(TestCase):
  117. def test_basic(self):
  118. # Create instance and make sure flags are working properly.
  119. instance = BitFieldTestModel.objects.create(flags=1)
  120. self.assertTrue(instance.flags.FLAG_0)
  121. self.assertFalse(instance.flags.FLAG_1)
  122. self.assertFalse(instance.flags.FLAG_2)
  123. self.assertFalse(instance.flags.FLAG_3)
  124. def test_regression_1425(self):
  125. # Creating new instances shouldn't allow negative values.
  126. instance = BitFieldTestModel.objects.create(flags=-1)
  127. self.assertEqual(instance.flags._value, 15)
  128. self.assertTrue(instance.flags.FLAG_0)
  129. self.assertTrue(instance.flags.FLAG_1)
  130. self.assertTrue(instance.flags.FLAG_2)
  131. self.assertTrue(instance.flags.FLAG_3)
  132. cursor = connection.cursor()
  133. flags_field = BitFieldTestModel._meta.get_field('flags')
  134. flags_db_column = flags_field.db_column or flags_field.name
  135. cursor.execute(
  136. "INSERT INTO %s (%s) VALUES (-1)" % (BitFieldTestModel._meta.db_table, flags_db_column)
  137. )
  138. # There should only be the one row we inserted through the cursor.
  139. instance = BitFieldTestModel.objects.get(flags=-1)
  140. self.assertTrue(instance.flags.FLAG_0)
  141. self.assertTrue(instance.flags.FLAG_1)
  142. self.assertTrue(instance.flags.FLAG_2)
  143. self.assertTrue(instance.flags.FLAG_3)
  144. instance.save()
  145. self.assertEqual(BitFieldTestModel.objects.filter(flags=15).count(), 2)
  146. self.assertEqual(BitFieldTestModel.objects.filter(flags__lt=0).count(), 0)
  147. def test_select(self):
  148. BitFieldTestModel.objects.create(flags=3)
  149. self.assertTrue(
  150. BitFieldTestModel.objects.filter(flags=BitFieldTestModel.flags.FLAG_1).exists()
  151. )
  152. self.assertTrue(
  153. BitFieldTestModel.objects.filter(flags=BitFieldTestModel.flags.FLAG_0).exists()
  154. )
  155. self.assertFalse(
  156. BitFieldTestModel.objects.exclude(flags=BitFieldTestModel.flags.FLAG_0).exists()
  157. )
  158. self.assertFalse(
  159. BitFieldTestModel.objects.exclude(flags=BitFieldTestModel.flags.FLAG_1).exists()
  160. )
  161. def test_update(self):
  162. instance = BitFieldTestModel.objects.create(flags=0)
  163. self.assertFalse(instance.flags.FLAG_0)
  164. BitFieldTestModel.objects.filter(pk=instance.pk).update(
  165. flags=bitor(F('flags'), BitFieldTestModel.flags.FLAG_1)
  166. )
  167. instance = BitFieldTestModel.objects.get(pk=instance.pk)
  168. self.assertTrue(instance.flags.FLAG_1)
  169. BitFieldTestModel.objects.filter(pk=instance.pk).update(
  170. flags=bitor(
  171. F('flags'), ((~BitFieldTestModel.flags.FLAG_0 | BitFieldTestModel.flags.FLAG_3))
  172. )
  173. )
  174. instance = BitFieldTestModel.objects.get(pk=instance.pk)
  175. self.assertFalse(instance.flags.FLAG_0)
  176. self.assertTrue(instance.flags.FLAG_1)
  177. self.assertTrue(instance.flags.FLAG_3)
  178. self.assertFalse(
  179. BitFieldTestModel.objects.filter(flags=BitFieldTestModel.flags.FLAG_0).exists()
  180. )
  181. BitFieldTestModel.objects.filter(pk=instance.pk).update(
  182. flags=bitand(F('flags'), ~BitFieldTestModel.flags.FLAG_3)
  183. )
  184. instance = BitFieldTestModel.objects.get(pk=instance.pk)
  185. self.assertFalse(instance.flags.FLAG_0)
  186. self.assertTrue(instance.flags.FLAG_1)
  187. self.assertFalse(instance.flags.FLAG_3)
  188. def test_update_with_handler(self):
  189. instance = BitFieldTestModel.objects.create(flags=0)
  190. self.assertFalse(instance.flags.FLAG_0)
  191. instance.flags.FLAG_1 = True
  192. BitFieldTestModel.objects.filter(pk=instance.pk).update(
  193. flags=bitor(F('flags'), instance.flags)
  194. )
  195. instance = BitFieldTestModel.objects.get(pk=instance.pk)
  196. self.assertTrue(instance.flags.FLAG_1)
  197. def test_negate(self):
  198. BitFieldTestModel.objects.create(
  199. flags=BitFieldTestModel.flags.FLAG_0 | BitFieldTestModel.flags.FLAG_1
  200. )
  201. BitFieldTestModel.objects.create(flags=BitFieldTestModel.flags.FLAG_1)
  202. self.assertEqual(
  203. BitFieldTestModel.objects.filter(flags=~BitFieldTestModel.flags.FLAG_0).count(), 1
  204. )
  205. self.assertEqual(
  206. BitFieldTestModel.objects.filter(flags=~BitFieldTestModel.flags.FLAG_1).count(), 0
  207. )
  208. self.assertEqual(
  209. BitFieldTestModel.objects.filter(flags=~BitFieldTestModel.flags.FLAG_2).count(), 2
  210. )
  211. def test_default_value(self):
  212. instance = BitFieldTestModel.objects.create()
  213. self.assertTrue(instance.flags.FLAG_0)
  214. self.assertTrue(instance.flags.FLAG_1)
  215. self.assertFalse(instance.flags.FLAG_2)
  216. self.assertFalse(instance.flags.FLAG_3)
  217. def test_binary_capacity(self):
  218. import math
  219. from django.db.models.fields import BigIntegerField
  220. # Local maximum value, slow canonical algorithm
  221. MAX_COUNT = int(math.floor(math.log(BigIntegerField.MAX_BIGINT, 2)))
  222. # Big flags list
  223. flags = ['f' + six.text_type(i) for i in range(100)]
  224. try:
  225. BitField(flags=flags[:MAX_COUNT])
  226. except ValueError:
  227. self.fail("It should work well with these flags")
  228. self.assertRaises(ValueError, BitField, flags=flags[:(MAX_COUNT + 1)])
  229. def test_dictionary_init(self):
  230. flags = {
  231. 0: 'zero',
  232. 1: 'first',
  233. 10: 'tenth',
  234. 2: 'second',
  235. 'wrongkey': 'wrongkey',
  236. 100: 'bigkey',
  237. -100: 'smallkey',
  238. }
  239. try:
  240. bf = BitField(flags)
  241. except ValueError:
  242. self.fail("It should work well with these flags")
  243. self.assertEquals(
  244. bf.flags, ['zero', 'first', 'second', '', '', '', '', '', '', '', 'tenth']
  245. )
  246. self.assertRaises(ValueError, BitField, flags={})
  247. self.assertRaises(ValueError, BitField, flags={'wrongkey': 'wrongkey'})
  248. self.assertRaises(ValueError, BitField, flags={'1': 'non_int_key'})
  249. def test_defaults_as_key_names(self):
  250. class TestModel(models.Model):
  251. flags = BitField(
  252. flags=('FLAG_0', 'FLAG_1', 'FLAG_2', 'FLAG_3', ), default=('FLAG_1', 'FLAG_2')
  253. )
  254. field = TestModel._meta.get_field('flags')
  255. self.assertEquals(field.default, TestModel.flags.FLAG_1 | TestModel.flags.FLAG_2)
  256. class BitFieldSerializationTest(TestCase):
  257. def test_can_unserialize_bithandler(self):
  258. bf = BitFieldTestModel()
  259. bf.flags.FLAG_0 = 1
  260. bf.flags.FLAG_1 = 0
  261. data = pickle.dumps(bf)
  262. inst = pickle.loads(data)
  263. self.assertTrue(inst.flags.FLAG_0)
  264. self.assertFalse(inst.flags.FLAG_1)
  265. def test_pickle_integration(self):
  266. inst = BitFieldTestModel.objects.create(flags=1)
  267. data = pickle.dumps(inst)
  268. inst = pickle.loads(data)
  269. self.assertEquals(type(inst.flags), BitHandler)
  270. self.assertEquals(int(inst.flags), 1)
  271. def test_added_field(self):
  272. bf = BitFieldTestModel()
  273. bf.flags.FLAG_0 = 1
  274. bf.flags.FLAG_1 = 0
  275. bf.flags.FLAG_3 = 0
  276. data = pickle.dumps(bf)
  277. inst = pickle.loads(data)
  278. self.assertTrue('FLAG_3' in inst.flags.keys())
  279. class BitFormFieldTest(TestCase):
  280. def test_form_new_invalid(self):
  281. invalid_data_dicts = [
  282. {
  283. 'flags': ['FLAG_0', 'FLAG_FLAG']
  284. }, {
  285. 'flags': ['FLAG_4']
  286. }, {
  287. 'flags': [1, 2]
  288. }
  289. ]
  290. for invalid_data in invalid_data_dicts:
  291. form = BitFieldTestModelForm(data=invalid_data)
  292. self.assertFalse(form.is_valid())
  293. def test_form_new(self):
  294. data_dicts = [{'flags': ['FLAG_0', 'FLAG_1']}, {'flags': ['FLAG_3']}, {'flags': []}, {}]
  295. for data in data_dicts:
  296. form = BitFieldTestModelForm(data=data)
  297. self.failUnless(form.is_valid())
  298. instance = form.save()
  299. flags = data['flags'] if 'flags' in data else []
  300. for k in BitFieldTestModel.flags:
  301. self.assertEquals(bool(getattr(instance.flags, k)), k in flags)
  302. def test_form_update(self):
  303. instance = BitFieldTestModel.objects.create(flags=0)
  304. for k in BitFieldTestModel.flags:
  305. self.assertFalse(bool(getattr(instance.flags, k)))
  306. data = {'flags': ['FLAG_0', 'FLAG_1']}
  307. form = BitFieldTestModelForm(data=data, instance=instance)
  308. self.failUnless(form.is_valid())
  309. instance = form.save()
  310. for k in BitFieldTestModel.flags:
  311. self.assertEquals(bool(getattr(instance.flags, k)), k in data['flags'])
  312. data = {'flags': ['FLAG_2', 'FLAG_3']}
  313. form = BitFieldTestModelForm(data=data, instance=instance)
  314. self.failUnless(form.is_valid())
  315. instance = form.save()
  316. for k in BitFieldTestModel.flags:
  317. self.assertEquals(bool(getattr(instance.flags, k)), k in data['flags'])
  318. data = {'flags': []}
  319. form = BitFieldTestModelForm(data=data, instance=instance)
  320. self.failUnless(form.is_valid())
  321. instance = form.save()
  322. for k in BitFieldTestModel.flags:
  323. self.assertFalse(bool(getattr(instance.flags, k)))