/kivy/tests/test_properties.py

https://github.com/geojeff/kivy
Python | 393 lines | 282 code | 94 blank | 17 comment | 6 complexity | 143e75f2e7cfeb8ff61005ee8edf8a05 MD5 | raw file
  1. '''
  2. Test properties attached to a widget
  3. '''
  4. import unittest
  5. from kivy.event import EventDispatcher
  6. from functools import partial
  7. class TestProperty(EventDispatcher):
  8. pass
  9. wid = TestProperty()
  10. class PropertiesTestCase(unittest.TestCase):
  11. def test_base(self):
  12. from kivy.properties import Property
  13. a = Property(-1)
  14. a.link(wid, 'a')
  15. a.link_deps(wid, 'a')
  16. self.assertEqual(a.get(wid), -1)
  17. a.set(wid, 0)
  18. self.assertEqual(a.get(wid), 0)
  19. a.set(wid, 1)
  20. self.assertEqual(a.get(wid), 1)
  21. def test_observer(self):
  22. from kivy.properties import Property
  23. a = Property(-1)
  24. a.link(wid, 'a')
  25. a.link_deps(wid, 'a')
  26. self.assertEqual(a.get(wid), -1)
  27. global observe_called
  28. observe_called = 0
  29. def observe(obj, value):
  30. global observe_called
  31. observe_called = 1
  32. a.bind(wid, observe)
  33. a.set(wid, 0)
  34. self.assertEqual(a.get(wid), 0)
  35. self.assertEqual(observe_called, 1)
  36. observe_called = 0
  37. a.set(wid, 0)
  38. self.assertEqual(a.get(wid), 0)
  39. self.assertEqual(observe_called, 0)
  40. a.set(wid, 1)
  41. self.assertEqual(a.get(wid), 1)
  42. self.assertEqual(observe_called, 1)
  43. def test_objectcheck(self):
  44. from kivy.properties import ObjectProperty
  45. a = ObjectProperty(False)
  46. a.link(wid, 'a')
  47. a.link_deps(wid, 'a')
  48. self.assertEqual(a.get(wid), False)
  49. a.set(wid, True)
  50. self.assertEqual(a.get(wid), True)
  51. def test_stringcheck(self):
  52. from kivy.properties import StringProperty
  53. a = StringProperty()
  54. a.link(wid, 'a')
  55. a.link_deps(wid, 'a')
  56. self.assertEqual(a.get(wid), '')
  57. a.set(wid, 'hello')
  58. self.assertEqual(a.get(wid), 'hello')
  59. try:
  60. a.set(wid, 88) # number shouldn't be accepted
  61. self.fail('string accept number, fail.')
  62. except ValueError:
  63. pass
  64. def test_numericcheck(self):
  65. from kivy.properties import NumericProperty
  66. a = NumericProperty()
  67. a.link(wid, 'a')
  68. a.link_deps(wid, 'a')
  69. self.assertEqual(a.get(wid), 0)
  70. a.set(wid, 99)
  71. self.assertEqual(a.get(wid), 99)
  72. #try:
  73. # a.set(wid, '') # string shouldn't be accepted
  74. # self.fail('number accept string, fail.')
  75. #except ValueError:
  76. # pass
  77. def test_listcheck(self):
  78. from kivy.properties import ListProperty
  79. a = ListProperty()
  80. a.link(wid, 'a')
  81. a.link_deps(wid, 'a')
  82. self.assertEqual(a.get(wid), [])
  83. a.set(wid, [1, 2, 3])
  84. self.assertEqual(a.get(wid), [1, 2, 3])
  85. def test_dictcheck(self):
  86. from kivy.properties import DictProperty
  87. a = DictProperty()
  88. a.link(wid, 'a')
  89. a.link_deps(wid, 'a')
  90. self.assertEqual(a.get(wid), {})
  91. a.set(wid, {'foo': 'bar'})
  92. self.assertEqual(a.get(wid), {'foo': 'bar'})
  93. def test_propertynone(self):
  94. from kivy.properties import NumericProperty
  95. a = NumericProperty(0, allownone=True)
  96. a.link(wid, 'a')
  97. a.link_deps(wid, 'a')
  98. self.assertEqual(a.get(wid), 0)
  99. try:
  100. a.set(wid, None)
  101. self.assertEqual(a.get(wid), None)
  102. except ValueError:
  103. pass
  104. a.set(wid, 1)
  105. self.assertEqual(a.get(wid), 1)
  106. def test_alias(self):
  107. from kivy.properties import NumericProperty, AliasProperty
  108. wid.__class__.x = x = NumericProperty(0)
  109. x.link(wid, 'x')
  110. x.link_deps(wid, 'x')
  111. wid.__class__.width = width = NumericProperty(100)
  112. width.link(wid, 'width')
  113. width.link_deps(wid, 'width')
  114. def get_right(self):
  115. return x.get(self) + width.get(self)
  116. def set_right(self, value):
  117. x.set(self, value - width.get(self))
  118. right = AliasProperty(get_right, set_right, bind=('x', 'width'))
  119. right.link(wid, 'right')
  120. right.link_deps(wid, 'right')
  121. self.assertEqual(right.get(wid), 100)
  122. x.set(wid, 500)
  123. self.assertEqual(right.get(wid), 600)
  124. width.set(wid, 50)
  125. self.assertEqual(right.get(wid), 550)
  126. right.set(wid, 100)
  127. self.assertEqual(width.get(wid), 50)
  128. self.assertEqual(x.get(wid), 50)
  129. # test observer
  130. global observe_called
  131. observe_called = 0
  132. def observe(obj, value):
  133. global observe_called
  134. observe_called = 1
  135. right.bind(wid, observe)
  136. x.set(wid, 100)
  137. self.assertEqual(observe_called, 1)
  138. observe_called = 0
  139. x.set(wid, 100)
  140. self.assertEqual(observe_called, 0)
  141. width.set(wid, 900)
  142. self.assertEqual(observe_called, 1)
  143. observe_called = 0
  144. right.set(wid, 700)
  145. self.assertEqual(observe_called, 1)
  146. observe_called = 0
  147. right.set(wid, 700)
  148. self.assertEqual(observe_called, 0)
  149. def test_reference(self):
  150. from kivy.properties import NumericProperty, ReferenceListProperty
  151. x = NumericProperty(0)
  152. x.link(wid, 'x')
  153. x.link_deps(wid, 'x')
  154. y = NumericProperty(0)
  155. y.link(wid, 'y')
  156. y.link_deps(wid, 'y')
  157. pos = ReferenceListProperty(x, y)
  158. pos.link(wid, 'pos')
  159. pos.link_deps(wid, 'pos')
  160. self.assertEqual(x.get(wid), 0)
  161. self.assertEqual(y.get(wid), 0)
  162. self.assertEqual(pos.get(wid), [0, 0])
  163. x.set(wid, 50)
  164. self.assertEqual(pos.get(wid), [50, 0])
  165. y.set(wid, 50)
  166. self.assertEqual(pos.get(wid), [50, 50])
  167. pos.set(wid, [0, 0])
  168. self.assertEqual(pos.get(wid), [0, 0])
  169. self.assertEqual(x.get(wid), 0)
  170. self.assertEqual(y.get(wid), 0)
  171. # test observer
  172. global observe_called
  173. observe_called = 0
  174. def observe(obj, value):
  175. global observe_called
  176. observe_called = 1
  177. pos.bind(wid, observe)
  178. self.assertEqual(observe_called, 0)
  179. x.set(wid, 99)
  180. self.assertEqual(observe_called, 1)
  181. def test_reference_child_update(self):
  182. from kivy.properties import NumericProperty, ReferenceListProperty
  183. x = NumericProperty(0)
  184. x.link(wid, 'x')
  185. x.link_deps(wid, 'x')
  186. y = NumericProperty(0)
  187. y.link(wid, 'y')
  188. y.link_deps(wid, 'y')
  189. pos = ReferenceListProperty(x, y)
  190. pos.link(wid, 'pos')
  191. pos.link_deps(wid, 'pos')
  192. pos.get(wid)[0] = 10
  193. self.assertEqual(pos.get(wid), [10, 0])
  194. pos.get(wid)[:] = (20, 30)
  195. self.assertEqual(pos.get(wid), [20, 30])
  196. def test_dict(self):
  197. from kivy.properties import DictProperty
  198. x = DictProperty()
  199. x.link(wid, 'x')
  200. x.link_deps(wid, 'x')
  201. # test observer
  202. global observe_called
  203. observe_called = 0
  204. def observe(obj, value):
  205. global observe_called
  206. observe_called = 1
  207. x.bind(wid, observe)
  208. observe_called = 0
  209. x.get(wid)['toto'] = 1
  210. self.assertEqual(observe_called, 1)
  211. observe_called = 0
  212. x.get(wid)['toto'] = 2
  213. self.assertEqual(observe_called, 1)
  214. observe_called = 0
  215. x.get(wid)['youupi'] = 2
  216. self.assertEqual(observe_called, 1)
  217. observe_called = 0
  218. del x.get(wid)['toto']
  219. self.assertEqual(observe_called, 1)
  220. observe_called = 0
  221. x.get(wid).update({'bleh': 5})
  222. self.assertEqual(observe_called, 1)
  223. def test_aliasproperty_with_cache(self):
  224. from kivy.properties import NumericProperty, AliasProperty
  225. global observe_called
  226. observe_called = 0
  227. class CustomAlias(EventDispatcher):
  228. basevalue = NumericProperty(1)
  229. def _get_prop(self):
  230. global observe_called
  231. observe_called += 1
  232. return self.basevalue * 2
  233. def _set_prop(self, value):
  234. self.basevalue = value / 2
  235. prop = AliasProperty(_get_prop, _set_prop,
  236. bind=('basevalue', ), cache=True)
  237. # initial checks
  238. wid = CustomAlias()
  239. self.assertEqual(observe_called, 0)
  240. self.assertEqual(wid.basevalue, 1)
  241. self.assertEqual(observe_called, 0)
  242. # first call, goes in cache
  243. self.assertEqual(wid.prop, 2)
  244. self.assertEqual(observe_called, 1)
  245. # second call, cache used
  246. self.assertEqual(wid.prop, 2)
  247. self.assertEqual(observe_called, 1)
  248. # change the base value, should trigger an update for the cache
  249. wid.basevalue = 4
  250. self.assertEqual(observe_called, 2)
  251. # now read the value again, should use the cache too
  252. self.assertEqual(wid.prop, 8)
  253. self.assertEqual(observe_called, 2)
  254. # change the prop itself, should trigger an update for the cache
  255. wid.prop = 4
  256. self.assertEqual(observe_called, 3)
  257. self.assertEqual(wid.basevalue, 2)
  258. self.assertEqual(wid.prop, 4)
  259. self.assertEqual(observe_called, 3)
  260. def test_bounded_numeric_property(self):
  261. from kivy.properties import BoundedNumericProperty
  262. bnp = BoundedNumericProperty(0.0, min=0.0, max=3.5)
  263. bnp.link(wid, 'bnp')
  264. bnp.set(wid, 1)
  265. bnp.set(wid, 0.0)
  266. bnp.set(wid, 3.1)
  267. bnp.set(wid, 3.5)
  268. self.assertRaises(ValueError, partial(bnp.set, wid, 3.6))
  269. self.assertRaises(ValueError, partial(bnp.set, wid, -3))
  270. def test_bounded_numeric_property_error_value(self):
  271. from kivy.properties import BoundedNumericProperty
  272. bnp = BoundedNumericProperty(0, min=-5, max=5, errorvalue=1)
  273. bnp.link(wid, 'bnp')
  274. bnp.set(wid, 1)
  275. self.assertEqual(bnp.get(wid), 1)
  276. bnp.set(wid, 5)
  277. self.assertEqual(bnp.get(wid), 5)
  278. bnp.set(wid, 6)
  279. self.assertEqual(bnp.get(wid), 1)
  280. bnp.set(wid, -5)
  281. self.assertEqual(bnp.get(wid), -5)
  282. bnp.set(wid, -6)
  283. self.assertEqual(bnp.get(wid), 1)
  284. def test_bounded_numeric_property_error_handler(self):
  285. from kivy.properties import BoundedNumericProperty
  286. bnp = BoundedNumericProperty(
  287. 0, min=-5, max=5,
  288. errorhandler=lambda x: 5 if x > 5 else -5)
  289. bnp.link(wid, 'bnp')
  290. bnp.set(wid, 1)
  291. self.assertEqual(bnp.get(wid), 1)
  292. bnp.set(wid, 5)
  293. self.assertEqual(bnp.get(wid), 5)
  294. bnp.set(wid, 10)
  295. self.assertEqual(bnp.get(wid), 5)
  296. bnp.set(wid, -5)
  297. self.assertEqual(bnp.get(wid), -5)
  298. bnp.set(wid, -10)
  299. self.assertEqual(bnp.get(wid), -5)