1# Copyright 2015 Anton Shestakov 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 2 of the License, or 6# (at your option) any later version. 7 8from tests.helper import ListWithUnused as L 9from tests.plugin import PluginTestCase 10from quodlibet.util.string.titlecase import human_title 11 12 13class TPluginStyle(PluginTestCase): 14 def conclude(self, fails): 15 def format_msg(f): 16 return "%s: '%s' plugin (%s)" % (f[1], f[0].name, f[0].cls) 17 if not fails: 18 return 19 grouped = {} 20 for f in fails: 21 grouped.setdefault(f[2], []).append(f) 22 lines = [] 23 for reason in grouped: 24 lines.append('== ' + reason + ' ==') 25 for f in grouped[reason]: 26 plugin, string = f[:2] 27 pclass = plugin.cls.__name__ 28 ppath = plugin.cls.__module__.rpartition('.plugins.')[2] 29 lines.append("%s.%s: %r" % (ppath, pclass, string)) 30 self.fail("One or more plugins did not pass:\n" + '\n'.join(lines)) 31 32 def test_plugin_name(self): 33 REASON_ABSENT = "plugin should have PLUGIN_NAME" 34 REASON_CASE = "PLUGIN_NAME should be in Title Case" 35 36 ok_names = L( 37 'Last.fm Cover Source', 'Last.fm Sync', 'Send to iFP', 38 'This is a test') 39 fails = [] 40 41 for pid, plugin in self.plugins.items(): 42 if not hasattr(plugin.cls, 'PLUGIN_NAME'): 43 fails.append((plugin, None, REASON_ABSENT)) 44 continue 45 name = plugin.cls.PLUGIN_NAME 46 if name != human_title(name): 47 if name not in ok_names: 48 fails.append((plugin, name, REASON_CASE)) 49 50 ok_names.check_unused() 51 self.conclude(fails) 52 53 def test_plugin_desc(self): 54 REASON_ABSENT = "plugin should have PLUGIN_DESC" 55 REASON_DOT = "PLUGIN_DESC should be a full sentence and end with a '.'" 56 57 skip_plugins = L('pickle_plugin') 58 fails = [] 59 60 for pid, plugin in self.plugins.items(): 61 if pid in skip_plugins: 62 continue 63 if not hasattr(plugin.cls, 'PLUGIN_DESC'): 64 fails.append((plugin, None, REASON_ABSENT)) 65 continue 66 desc = plugin.cls.PLUGIN_DESC 67 if not desc.endswith('.'): 68 fails.append((plugin, desc, REASON_DOT)) 69 70 skip_plugins.check_unused() 71 self.conclude(fails) 72