88
99from sqlalchemy import MetaData
1010
11+ from cloudbot .event import Event , CommandEvent , RegexEvent , CapEvent , PostHookEvent , IrcOutEvent
1112from cloudbot .hook import Action
1213from cloudbot .plugin import Plugin , Hook
14+ from cloudbot .util import database
15+
16+ database .metadata = MetaData ()
17+ Hook .original_init = Hook .__init__
18+
19+ PLUGINS = []
20+
21+
22+ class MockBot :
23+ def __init__ (self ):
24+ self .loop = None
1325
1426
1527def patch_hook_init (self , _type , plugin , func_hook ):
1628 self .original_init (_type , plugin , func_hook )
29+ self .func_hook = func_hook
30+
1731
18- assert not func_hook .kwargs , \
19- "Unknown arguments '{}' passed during registration of hook '{}'" .format (func_hook .kwargs , self .function_name )
32+ Hook .__init__ = patch_hook_init
2033
2134
2235def gather_plugins ():
@@ -25,14 +38,7 @@ def gather_plugins():
2538 return path_list
2639
2740
28- def load_plugin (plugin_path , monkeypatch ):
29- if not hasattr (Hook , "original_init" ):
30- monkeypatch .setattr ('cloudbot.plugin.Hook.original_init' , Hook .__init__ , raising = False )
31-
32- monkeypatch .setattr ('cloudbot.plugin.Hook.__init__' , patch_hook_init )
33-
34- monkeypatch .setattr ('cloudbot.util.database.metadata' , MetaData ())
35-
41+ def load_plugin (plugin_path ):
3642 path = Path (plugin_path )
3743 file_path = path .resolve ()
3844 file_name = file_path .name
@@ -47,10 +53,23 @@ def load_plugin(plugin_path, monkeypatch):
4753 return Plugin (str (file_path ), file_name , title , plugin_module )
4854
4955
56+ def get_plugins ():
57+ if not PLUGINS :
58+ PLUGINS .extend (map (load_plugin , gather_plugins ()))
59+
60+ return PLUGINS
61+
62+
5063def pytest_generate_tests (metafunc ):
51- if 'plugin_path' in metafunc .fixturenames :
52- paths = list (gather_plugins ())
53- metafunc .parametrize ('plugin_path' , paths , ids = list (map (str , paths )))
64+ if 'plugin' in metafunc .fixturenames :
65+ plugins = get_plugins ()
66+ metafunc .parametrize ('plugin' , plugins , ids = [plugin .title for plugin in plugins ])
67+ elif 'hook' in metafunc .fixturenames :
68+ plugins = get_plugins ()
69+ hooks = [hook for plugin in plugins for hook_list in plugin .hooks .values () for hook in hook_list ]
70+ metafunc .parametrize (
71+ 'hook' , hooks , ids = ["{}.{}" .format (hook .plugin .title , hook .function_name ) for hook in hooks ]
72+ )
5473
5574
5675HOOK_ATTR_TYPES = {
@@ -69,15 +88,12 @@ def pytest_generate_tests(metafunc):
6988}
7089
7190
72- def test_plugin (plugin_path , monkeypatch ):
73- plugin = load_plugin (plugin_path , monkeypatch )
74- for hooks in plugin .hooks .values ():
75- for hook in hooks :
76- _test_hook (hook )
77-
91+ def test_hook_kwargs (hook ):
92+ assert not hook .func_hook .kwargs , \
93+ "Unknown arguments '{}' passed during registration of hook '{}'" .format (
94+ hook .func_hook .kwargs , hook .function_name
95+ )
7896
79- def _test_hook (hook ):
80- assert 'async' not in hook .required_args , "Use of deprecated function Event.async"
8197 for name , types in HOOK_ATTR_TYPES .items ():
8298 try :
8399 attr = getattr (hook , name )
@@ -87,6 +103,33 @@ def _test_hook(hook):
87103 assert isinstance (attr , types ), \
88104 "Unexpected type '{}' for hook attribute '{}'" .format (type (attr ).__name__ , name )
89105
106+
107+ def test_hook_doc (hook ):
90108 if hook .type == "command" and hook .doc :
91109 assert hook .doc [:1 ] not in "." + string .ascii_letters , \
92110 "Invalid docstring '{}' format for command hook" .format (hook .doc )
111+
112+
113+ def test_hook_args (hook ):
114+ assert 'async' not in hook .required_args , "Use of deprecated function Event.async"
115+
116+ bot = MockBot ()
117+ if hook .type in ("irc_raw" , "perm_check" , "periodic" , "on_start" , "on_stop" , "event" , "on_connect" ):
118+ event = Event (bot = bot )
119+ elif hook .type == "command" :
120+ event = CommandEvent (bot = bot , hook = hook , text = "" , triggered_command = "" )
121+ elif hook .type == "regex" :
122+ event = RegexEvent (bot = bot , hook = hook , match = None )
123+ elif hook .type .startswith ("on_cap" ):
124+ event = CapEvent (bot = bot , cap = "" )
125+ elif hook .type == "post_hook" :
126+ event = PostHookEvent (bot = bot )
127+ elif hook .type == "irc_out" :
128+ event = IrcOutEvent (bot = bot )
129+ elif hook .type == "sieve" :
130+ return
131+ else :
132+ assert False , "Unhandled hook type '{}' in tests" .format (hook .type )
133+
134+ for arg in hook .required_args :
135+ assert hasattr (event , arg ), "Undefined parameter '{}' for hook function" .format (arg )
0 commit comments