/openmdao.util/src/openmdao/util/test/test_decorators.py

https://github.com/thearn/OpenMDAO-Framework · Python · 340 lines · 274 code · 66 blank · 0 comment · 35 complexity · e08035d26ae11eb56c9272dc6095c455 MD5 · raw file

  1. import unittest
  2. from inspect import getmembers, ismethod
  3. from types import NoneType
  4. from traits.api import HasTraits, Float
  5. from zope.interface import Interface, implements, implementedBy
  6. from openmdao.main.interfaces import obj_has_interface
  7. from openmdao.util.decorators import add_delegate, \
  8. stub_if_missing_deps, method_accepts, function_accepts
  9. class GoodDelegate(object):
  10. cls_x = 4
  11. def __init__(self, parent):
  12. self.inst_y = 3
  13. def del_amethod(self, a, b, c):
  14. return sum([a,b,c,self.inst_y])
  15. def _priv_method(self):
  16. pass
  17. class InheritedDelegate(GoodDelegate):
  18. def inherited_amethod(self, a, b, c):
  19. return sum([a,b,c,self.inst_y])
  20. class BadDelegate1(object):
  21. def __init__(self, parent):
  22. self.inst_y = 3
  23. def del_amethod(self, a, b, c):
  24. return sum(a,b,c,self.inst_y)
  25. def cls_x(self):
  26. return 9
  27. def _priv_method(self):
  28. pass
  29. class BadDelegate2(object):
  30. def __init__(self, parent):
  31. self.inst_y = 3
  32. def amethod(self):
  33. return self.inst_y
  34. class I(Interface):
  35. def i(a):
  36. pass
  37. class J(I):
  38. def j(a):
  39. pass
  40. class DelegateI(object):
  41. implements(I)
  42. def __init__(self, parent):
  43. pass
  44. def i(self, a):
  45. return a + 1
  46. class DelegateJ(object):
  47. implements(J)
  48. def __init__(self, parent):
  49. pass
  50. def i(self, a):
  51. return a + 1
  52. def j(self, a):
  53. return a + 2
  54. class InheritedDelegateI(DelegateI):
  55. def __init__(self, parent):
  56. super(InheritedDelegateI, self).__init__(parent)
  57. class DelegateTestCase(unittest.TestCase):
  58. def test_add_delegate(self):
  59. @add_delegate(GoodDelegate)
  60. class Foo(object):
  61. cls_x = 1
  62. def __init__(self):
  63. self.inst_x = 9
  64. def amethod(self, a, b, c='foo'): pass
  65. def genmethod(self, *args, **kwargs): pass
  66. def _priv_method(self): pass
  67. mems = set([n for n,v in getmembers(Foo,ismethod) if not n.startswith('_')])
  68. self.assertEqual(mems, set(['amethod','del_amethod','genmethod']))
  69. f = Foo()
  70. self.assertEqual(f.del_amethod(1,2,0), 6)
  71. self.assertTrue(hasattr(f,'_gooddelegate'))
  72. def test_inheritance(self):
  73. @add_delegate(InheritedDelegate)
  74. class Foo(object):
  75. cls_x = 1
  76. def __init__(self):
  77. self.inst_x = 9
  78. def amethod(self, a, b, c='foo'): pass
  79. def genmethod(self, *args, **kwargs): pass
  80. def _priv_method(self): pass
  81. mems = set([n for n,v in getmembers(Foo,ismethod) if not n.startswith('_')])
  82. self.assertEqual(mems, set(['amethod','inherited_amethod','del_amethod','genmethod']))
  83. f = Foo()
  84. self.assertEqual(f.inherited_amethod(1,2,0), 6)
  85. def test_add_delegate_bad1(self):
  86. @add_delegate(BadDelegate1)
  87. class Foo(object):
  88. cls_x = 1234 # BadDelegate1 defines this as a method
  89. def __init__(self):
  90. self.inst_x = 9
  91. def amethod(self, a, b, c='foo'): pass
  92. def genmethod(self, *args, **kwargs): pass
  93. def _priv_method(self): pass
  94. f = Foo()
  95. self.assertEqual(f.cls_x, 1234)
  96. def test_add_delegate_bad2(self):
  97. @add_delegate(BadDelegate2)
  98. class Foo2(object):
  99. cls_x = 4567
  100. def __init__(self):
  101. self.inst_x = 9
  102. def amethod(self, a, b, c='foo'): return 87 #BadDelegate2 defines this
  103. def genmethod(self, *args, **kwargs): pass
  104. def _priv_method(self): pass
  105. f = Foo2()
  106. self.assertEqual(f.amethod(1,2), 87)
  107. def test_add_delegate_bad1_hastraits(self):
  108. @add_delegate(BadDelegate1)
  109. class Foo3(HasTraits):
  110. cls_x = Float(3.456,iotype='in')
  111. def __init__(self):
  112. self.inst_x = 9
  113. def amethod(self, a, b, c='foo'): pass
  114. def genmethod(self, *args, **kwargs): pass
  115. def _priv_method(self): pass
  116. f = Foo3()
  117. self.assertEqual(f.cls_x, 3.456)
  118. def test_add_delegate_bad2_hastraits(self):
  119. @add_delegate(BadDelegate2)
  120. class Foo4(HasTraits):
  121. cls_x = 1
  122. def __init__(self):
  123. self.inst_x = 9
  124. def amethod(self, a, b, c='foo'): return -54.3
  125. def genmethod(self, *args, **kwargs): pass
  126. def _priv_method(self): pass
  127. f = Foo4()
  128. self.assertEqual(f.amethod(1,2), -54.3)
  129. def test_add_delegatei(self):
  130. @add_delegate(DelegateI)
  131. class Delegator(object):
  132. def __init__(self):
  133. self.x = 1
  134. mems = set([n for n,v in getmembers(Delegator, ismethod) if not n.startswith('_')])
  135. self.assertEqual(mems, set(['i']))
  136. interfaces = list(implementedBy(Delegator))
  137. self.assertEqual(interfaces, list(implementedBy(DelegateI)))
  138. delegator = Delegator()
  139. for interface in interfaces:
  140. self.assertTrue(obj_has_interface(delegator, interface))
  141. self.assertEqual(delegator.i(delegator.x), 2)
  142. def test_add_delegatej(self):
  143. @add_delegate(DelegateJ)
  144. class Delegator1(object):
  145. def __init__(self):
  146. self.x = 1
  147. mems = set([n for n,v in getmembers(Delegator1, ismethod) if not n.startswith('_')])
  148. self.assertEqual(mems, set(['i', 'j']))
  149. interfaces = list(implementedBy(Delegator1))
  150. self.assertEqual(interfaces, list(implementedBy(DelegateJ)))
  151. delegator = Delegator1()
  152. for interface in interfaces:
  153. self.assertTrue(obj_has_interface(delegator, interface))
  154. self.assertEqual(delegator.i(delegator.x), 2)
  155. self.assertEqual(delegator.j(delegator.x), 3)
  156. def test_add_inheriteddelegatei(self):
  157. @add_delegate(InheritedDelegateI)
  158. class Delegator2(object):
  159. def __init__(self):
  160. self.x = 1
  161. mems = set([n for n,v in getmembers(Delegator2, ismethod) if not n.startswith('_')])
  162. self.assertEqual(mems, set(['i']))
  163. interfaces = list(implementedBy(Delegator2))
  164. self.assertEqual(interfaces, list(implementedBy(InheritedDelegateI)))
  165. delegator = Delegator2()
  166. for interface in interfaces:
  167. self.assertTrue(obj_has_interface(delegator, interface))
  168. self.assertEqual(delegator.i(delegator.x), 2)
  169. class StubIfMissingTestCase(unittest.TestCase):
  170. def test_stub_class(self):
  171. @stub_if_missing_deps('FooBar', 'math', 'blah')
  172. class MyClass(object):
  173. pass
  174. try:
  175. c = MyClass()
  176. except RuntimeError as err:
  177. self.assertEqual(str(err),
  178. "The MyClass class depends on the following modules or attributes which were not found on your system: ['FooBar', 'blah']")
  179. else:
  180. self.fail("expected RuntimeError")
  181. def test_stub_funct(self):
  182. @stub_if_missing_deps('abcdef', 'Krusty', 'math')
  183. def funct(a, b, c, d):
  184. return True
  185. try:
  186. f = funct(1,2,3,4)
  187. except RuntimeError as err:
  188. self.assertEqual(str(err), "The funct function depends on the following modules or attributes which were not found on your system: ['abcdef', 'Krusty']")
  189. else:
  190. self.fail("expected RuntimeError")
  191. def test_stub_method(self):
  192. class TheClass(object):
  193. @stub_if_missing_deps('somemodule','fooey')
  194. def my_method(self, a, b, c, d):
  195. return True
  196. c = TheClass()
  197. try:
  198. c.my_method(1,2,3,4)
  199. except RuntimeError as err:
  200. self.assertEqual(str(err), "The my_method function depends on the following modules or attributes which were not found on your system: ['somemodule', 'fooey']")
  201. else:
  202. self.fail("expected RuntimeError")
  203. class AcceptsTestCase(unittest.TestCase):
  204. def test_method_accepts(self):
  205. class Foo(object):
  206. @method_accepts(TypeError,
  207. compnames=(str,list,tuple),
  208. index=(int,NoneType),
  209. check=bool)
  210. def add(self, compnames, index=None, check=False):
  211. print 'ok'
  212. f = Foo()
  213. try:
  214. f.add( 'comp1', 'comp2' )
  215. except TypeError as err:
  216. self.assertEqual(str(err), "Method argument 'index' with "
  217. "a value of 'comp2' does "
  218. "not match the allowed types "
  219. "(<type 'int'>, <type 'NoneType'>). \n"
  220. " The arguments of this method have allowed "
  221. "types of index=(<type 'int'>, <type 'NoneType'>), "
  222. "check=<type 'bool'>, "
  223. "compnames=(<type 'str'>, <type 'list'>, <type 'tuple'>)")
  224. else:
  225. self.fail("expected TypeError")
  226. try:
  227. f.add( 'comp1', check = 1.0 )
  228. except TypeError as err:
  229. self.assertEqual(str(err), "Method argument 'check' with a "
  230. "value of 1.0 does not match one "
  231. "of the allowed types <type 'bool'>. \n"
  232. " The arguments of this method "
  233. "have allowed types of "
  234. "index=(<type 'int'>, "
  235. "<type 'NoneType'>), check=<type 'bool'>, "
  236. "compnames=(<type 'str'>, <type 'list'>, <type 'tuple'>)" )
  237. else:
  238. self.fail("expected TypeError")
  239. def test_function_accepts(self):
  240. @function_accepts(TypeError,
  241. compnames=(str,list,tuple),
  242. index=(int,NoneType),
  243. check=bool)
  244. def add(compnames, index=None, check=False):
  245. print 'ok'
  246. try:
  247. add( 'comp1', 'comp2' )
  248. except TypeError as err:
  249. self.assertEqual(str(err), "Function argument 'index' with "
  250. "a value of 'comp2' does "
  251. "not match the allowed types "
  252. "(<type 'int'>, <type 'NoneType'>). \n"
  253. " The arguments of this function "
  254. "have allowed types of "
  255. "index=(<type 'int'>, "
  256. "<type 'NoneType'>), check=<type 'bool'>, "
  257. "compnames=(<type 'str'>, <type 'list'>, <type 'tuple'>)")
  258. else:
  259. self.fail("expected TypeError")
  260. try:
  261. add( 'comp1', check = 1.0 )
  262. except TypeError as err:
  263. self.assertEqual(str(err), "Function argument 'check' with a "
  264. "value of 1.0 does not match one "
  265. "of the allowed types <type 'bool'>. \n"
  266. " The arguments of this function have "
  267. "allowed types of "
  268. "index=(<type 'int'>, <type 'NoneType'>), "
  269. "check=<type 'bool'>, "
  270. "compnames=(<type 'str'>, <type 'list'>, <type 'tuple'>)" )
  271. else:
  272. self.fail("expected TypeError")
  273. if __name__ == '__main__':
  274. unittest.main()