ut_lockable.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #!/usr/bin/env python3
  2. """
  3. test.unit_tests_d.ut_lockable: unit test for the MMGen suite's Lockable class
  4. """
  5. from ..include.common import qmsg,qmsg_r,vmsg
  6. class unit_test:
  7. def run_test(self,name,ut):
  8. from mmgen.base_obj import AttrCtrl,Lockable
  9. from decimal import Decimal
  10. qmsg_r('Testing class AttrCtrl...')
  11. class MyAttrCtrl(AttrCtrl):
  12. _autolock = False
  13. foo = 'fooval'
  14. ac = MyAttrCtrl()
  15. ac._lock()
  16. ac.foo = 'new fooval'
  17. ac.foo = 'new fooval2'
  18. class MyAttrCtrlAutolock(AttrCtrl):
  19. pass
  20. aca = MyAttrCtrlAutolock()
  21. class MyAttrCtrlClsCheck(AttrCtrl):
  22. _autolock = False
  23. _use_class_attr = True
  24. foo = 'fooval'
  25. bar = None
  26. acc = MyAttrCtrlClsCheck()
  27. acc._lock()
  28. acc.foo = 'new_fooval'
  29. acc.foo = 'new_fooval2'
  30. acc.bar = 'bar val'
  31. acc.bar = 1 # class attribute bar is None, so can be set to any type
  32. class MyAttrCtrlDflNone(AttrCtrl):
  33. _default_to_none = True
  34. foo = 'fooval'
  35. bar = None
  36. acdn = MyAttrCtrlDflNone()
  37. assert acdn.foo == 'fooval', f'{acdn.foo}'
  38. assert acdn.bar is None, f'{acdn.bar}'
  39. assert acdn.baz is None, f'{acdn.baz}'
  40. qmsg('OK')
  41. qmsg_r('Testing class Lockable...')
  42. class MyLockable(Lockable): # class without attrs
  43. _autolock = False
  44. _set_ok = ('foo','baz','alpha','beta','gamma','delta','epsilon')
  45. _reset_ok = ('bar','baz')
  46. lc = MyLockable()
  47. lc.foo = None
  48. lc.bar = 'barval'
  49. lc.baz = 1
  50. lc.qux = 1
  51. # are these considered set?
  52. lc.alpha = 0 # yes
  53. lc.beta = False # yes
  54. lc.gamma = Decimal('0') # yes
  55. lc.delta = 0.0 # yes
  56. lc.epsilon = [] # no
  57. lc._lock()
  58. lc.foo = 'fooval2'
  59. lc.bar = 'barval2'
  60. lc.bar = 'barval3'
  61. lc.baz = 2
  62. lc.baz = 3
  63. lc.epsilon = [0]
  64. class MyLockableClsCheck(Lockable): # class with attrs
  65. _autolock = False
  66. _use_class_attr = True
  67. _set_ok = ('foo','baz')
  68. _reset_ok = ('bar','baz')
  69. foo = None
  70. bar = 1
  71. baz = 3.5
  72. qux = 'quxval'
  73. lcc = MyLockableClsCheck()
  74. lcc._lock()
  75. lcc.foo = 'fooval2' # class attribute foo is None, so can be set to any type
  76. lcc.bar = 2
  77. lcc.bar = 3 # bar is in reset list
  78. lcc.baz = 3.2
  79. lcc.baz = 3.1 # baz is in both lists
  80. qmsg('OK')
  81. qmsg_r('Testing class Lockable with autolock...')
  82. class MyLockableAutolock(Lockable):
  83. def __init__(self):
  84. self.foo = True
  85. lca = MyLockableAutolock()
  86. assert lca._autolock is True
  87. assert lca._locked is True
  88. assert lca.foo is True
  89. class MyLockableAutolockDflNone(Lockable):
  90. _default_to_none = True
  91. foo = 0
  92. lcdn = MyLockableAutolockDflNone()
  93. assert lcdn.foo == 0
  94. assert lcdn.bar == None
  95. class MyLockableBad(Lockable):
  96. _set_ok = ('foo','bar')
  97. foo = 1
  98. qmsg('OK')
  99. qmsg_r('Checking error handling...')
  100. vmsg('')
  101. def bad1(): ac.x = 1
  102. def bad2(): acc.foo = 1
  103. def bad3(): lc.foo = 'fooval3'
  104. def bad4(): lc.baz = 'str'
  105. def bad5(): lcc.bar = 'str'
  106. def bad6(): lc.qux = 2
  107. def bad7(): lcc.qux = 'quxval2'
  108. def bad8(): lcc.foo = 'fooval3'
  109. def bad9(): lc.x = 1
  110. def bad10(): lcc.x = 1
  111. def bad11(): lc.alpha = 0
  112. def bad12(): lc.beta = False
  113. def bad13(): lc.gamma = Decimal('0')
  114. def bad14(): lc.delta = float(0)
  115. def bad15(): lc.epsilon = [0]
  116. def bad16(): lca.foo = None
  117. def bad17(): lb = MyLockableBad()
  118. def bad18(): aca._lock()
  119. def bad19(): acdn.baz = None
  120. def bad20(): lcdn.foo = 1
  121. def bad21(): lcdn.bar = None
  122. def bad22(): del lcdn.foo
  123. ut.process_bad_data((
  124. ('attr (1)', 'AttributeError', 'has no attr', bad1 ),
  125. ('attr (2)', 'AttributeError', 'has no attr', bad9 ),
  126. ('attr (3)', 'AttributeError', 'has no attr', bad10 ),
  127. ('attr (4)', 'AttributeError', 'has no attr', bad19 ),
  128. ('attr (5)', 'AttributeError', 'has no attr', bad21 ),
  129. ('attr type (1)', 'AttributeError', 'type', bad2 ),
  130. ("attr type (2)", 'AttributeError', 'type', bad4 ),
  131. ("attr type (3)", 'AttributeError', 'type', bad5 ),
  132. ("attr (can't set)", 'AttributeError', 'read-only', bad6 ),
  133. ("attr (can't set)", 'AttributeError', 'read-only', bad7 ),
  134. ("attr (can't set)", 'AttributeError', 'read-only', bad20 ),
  135. ("attr (can't reset)", 'AttributeError', 'reset', bad3 ),
  136. ("attr (can't reset)", 'AttributeError', 'reset', bad8 ),
  137. ("attr (can't reset)", 'AttributeError', 'reset', bad11 ),
  138. ("attr (can't reset)", 'AttributeError', 'reset', bad12 ),
  139. ("attr (can't reset)", 'AttributeError', 'reset', bad13 ),
  140. ("attr (can't reset)", 'AttributeError', 'reset', bad14 ),
  141. ("attr (can't reset)", 'AttributeError', 'reset', bad15 ),
  142. ("attr (can't set)", 'AttributeError', 'read-only', bad16 ),
  143. ("attr (bad _set_ok)", 'AssertionError', 'not found in',bad17 ),
  144. ("attr (can’t delete)",'AttributeError', 'not be delet',bad22 ),
  145. ("call to _lock()", 'AssertionError', 'only once', bad18 ),
  146. ))
  147. qmsg('OK')
  148. return True