test_hookcaller.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. import pytest
  2. from pluggy import HookimplMarker, HookspecMarker
  3. from pluggy.hooks import HookImpl
  4. hookspec = HookspecMarker("example")
  5. hookimpl = HookimplMarker("example")
  6. @pytest.fixture
  7. def hc(pm):
  8. class Hooks(object):
  9. @hookspec
  10. def he_method1(self, arg):
  11. pass
  12. pm.add_hookspecs(Hooks)
  13. return pm.hook.he_method1
  14. @pytest.fixture
  15. def addmeth(hc):
  16. def addmeth(tryfirst=False, trylast=False, hookwrapper=False):
  17. def wrap(func):
  18. hookimpl(tryfirst=tryfirst, trylast=trylast, hookwrapper=hookwrapper)(func)
  19. hc._add_hookimpl(HookImpl(None, "<temp>", func, func.example_impl))
  20. return func
  21. return wrap
  22. return addmeth
  23. def funcs(hookmethods):
  24. return [hookmethod.function for hookmethod in hookmethods]
  25. def test_adding_nonwrappers(hc, addmeth):
  26. @addmeth()
  27. def he_method1():
  28. pass
  29. @addmeth()
  30. def he_method2():
  31. pass
  32. @addmeth()
  33. def he_method3():
  34. pass
  35. assert funcs(hc._nonwrappers) == [he_method1, he_method2, he_method3]
  36. def test_adding_nonwrappers_trylast(hc, addmeth):
  37. @addmeth()
  38. def he_method1_middle():
  39. pass
  40. @addmeth(trylast=True)
  41. def he_method1():
  42. pass
  43. @addmeth()
  44. def he_method1_b():
  45. pass
  46. assert funcs(hc._nonwrappers) == [he_method1, he_method1_middle, he_method1_b]
  47. def test_adding_nonwrappers_trylast3(hc, addmeth):
  48. @addmeth()
  49. def he_method1_a():
  50. pass
  51. @addmeth(trylast=True)
  52. def he_method1_b():
  53. pass
  54. @addmeth()
  55. def he_method1_c():
  56. pass
  57. @addmeth(trylast=True)
  58. def he_method1_d():
  59. pass
  60. assert funcs(hc._nonwrappers) == [
  61. he_method1_d,
  62. he_method1_b,
  63. he_method1_a,
  64. he_method1_c,
  65. ]
  66. def test_adding_nonwrappers_trylast2(hc, addmeth):
  67. @addmeth()
  68. def he_method1_middle():
  69. pass
  70. @addmeth()
  71. def he_method1_b():
  72. pass
  73. @addmeth(trylast=True)
  74. def he_method1():
  75. pass
  76. assert funcs(hc._nonwrappers) == [he_method1, he_method1_middle, he_method1_b]
  77. def test_adding_nonwrappers_tryfirst(hc, addmeth):
  78. @addmeth(tryfirst=True)
  79. def he_method1():
  80. pass
  81. @addmeth()
  82. def he_method1_middle():
  83. pass
  84. @addmeth()
  85. def he_method1_b():
  86. pass
  87. assert funcs(hc._nonwrappers) == [he_method1_middle, he_method1_b, he_method1]
  88. def test_adding_wrappers_ordering(hc, addmeth):
  89. @addmeth(hookwrapper=True)
  90. def he_method1():
  91. pass
  92. @addmeth()
  93. def he_method1_middle():
  94. pass
  95. @addmeth(hookwrapper=True)
  96. def he_method3():
  97. pass
  98. assert funcs(hc._nonwrappers) == [he_method1_middle]
  99. assert funcs(hc._wrappers) == [he_method1, he_method3]
  100. def test_adding_wrappers_ordering_tryfirst(hc, addmeth):
  101. @addmeth(hookwrapper=True, tryfirst=True)
  102. def he_method1():
  103. pass
  104. @addmeth(hookwrapper=True)
  105. def he_method2():
  106. pass
  107. assert hc._nonwrappers == []
  108. assert funcs(hc._wrappers) == [he_method2, he_method1]
  109. def test_hookspec(pm):
  110. class HookSpec(object):
  111. @hookspec()
  112. def he_myhook1(arg1):
  113. pass
  114. @hookspec(firstresult=True)
  115. def he_myhook2(arg1):
  116. pass
  117. @hookspec(firstresult=False)
  118. def he_myhook3(arg1):
  119. pass
  120. pm.add_hookspecs(HookSpec)
  121. assert not pm.hook.he_myhook1.spec.opts["firstresult"]
  122. assert pm.hook.he_myhook2.spec.opts["firstresult"]
  123. assert not pm.hook.he_myhook3.spec.opts["firstresult"]
  124. @pytest.mark.parametrize("name", ["hookwrapper", "optionalhook", "tryfirst", "trylast"])
  125. @pytest.mark.parametrize("val", [True, False])
  126. def test_hookimpl(name, val):
  127. @hookimpl(**{name: val})
  128. def he_myhook1(arg1):
  129. pass
  130. if val:
  131. assert he_myhook1.example_impl.get(name)
  132. else:
  133. assert not hasattr(he_myhook1, name)
  134. def test_hookrelay_registry(pm):
  135. """Verify hook caller instances are registered by name onto the relay
  136. and can be likewise unregistered."""
  137. class Api(object):
  138. @hookspec
  139. def hello(self, arg):
  140. "api hook 1"
  141. pm.add_hookspecs(Api)
  142. hook = pm.hook
  143. assert hasattr(hook, "hello")
  144. assert repr(hook.hello).find("hello") != -1
  145. class Plugin(object):
  146. @hookimpl
  147. def hello(self, arg):
  148. return arg + 1
  149. plugin = Plugin()
  150. pm.register(plugin)
  151. out = hook.hello(arg=3)
  152. assert out == [4]
  153. assert not hasattr(hook, "world")
  154. pm.unregister(plugin)
  155. assert hook.hello(arg=3) == []