tests.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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. {"flags": ["FLAG_0", "FLAG_FLAG"]},
  283. {"flags": ["FLAG_4"]},
  284. {"flags": [1, 2]},
  285. ]
  286. for invalid_data in invalid_data_dicts:
  287. form = BitFieldTestModelForm(data=invalid_data)
  288. self.assertFalse(form.is_valid())
  289. def test_form_new(self):
  290. data_dicts = [{"flags": ["FLAG_0", "FLAG_1"]}, {"flags": ["FLAG_3"]}, {"flags": []}, {}]
  291. for data in data_dicts:
  292. form = BitFieldTestModelForm(data=data)
  293. self.failUnless(form.is_valid())
  294. instance = form.save()
  295. flags = data["flags"] if "flags" in data else []
  296. for k in BitFieldTestModel.flags:
  297. self.assertEquals(bool(getattr(instance.flags, k)), k in flags)
  298. def test_form_update(self):
  299. instance = BitFieldTestModel.objects.create(flags=0)
  300. for k in BitFieldTestModel.flags:
  301. self.assertFalse(bool(getattr(instance.flags, k)))
  302. data = {"flags": ["FLAG_0", "FLAG_1"]}
  303. form = BitFieldTestModelForm(data=data, instance=instance)
  304. self.failUnless(form.is_valid())
  305. instance = form.save()
  306. for k in BitFieldTestModel.flags:
  307. self.assertEquals(bool(getattr(instance.flags, k)), k in data["flags"])
  308. data = {"flags": ["FLAG_2", "FLAG_3"]}
  309. form = BitFieldTestModelForm(data=data, instance=instance)
  310. self.failUnless(form.is_valid())
  311. instance = form.save()
  312. for k in BitFieldTestModel.flags:
  313. self.assertEquals(bool(getattr(instance.flags, k)), k in data["flags"])
  314. data = {"flags": []}
  315. form = BitFieldTestModelForm(data=data, instance=instance)
  316. self.failUnless(form.is_valid())
  317. instance = form.save()
  318. for k in BitFieldTestModel.flags:
  319. self.assertFalse(bool(getattr(instance.flags, k)))