diff --git a/senpy/plugins/__init__.py b/senpy/plugins/__init__.py index ec88142..754966a 100644 --- a/senpy/plugins/__init__.py +++ b/senpy/plugins/__init__.py @@ -15,36 +15,12 @@ import subprocess import importlib import yaml -from .. import models +from .. import models, utils from ..api import API_PARAMS logger = logging.getLogger(__name__) -def check_template(indict, template): - if isinstance(template, dict) and isinstance(indict, dict): - for k, v in template.items(): - if k not in indict: - return '{} not in {}'.format(k, indict) - check_template(indict[k], v) - elif isinstance(template, list) and isinstance(indict, list): - if len(indict) != len(template): - raise models.Error('Different size for {} and {}'.format(indict, template)) - for e in template: - found = False - for i in indict: - try: - check_template(i, e) - found = True - except models.Error as ex: - continue - if not found: - raise models.Error('{} not found in {}'.format(e, indict)) - else: - if indict != template: - raise models.Error('{} and {} are different'.format(indict, template)) - - class Plugin(models.Plugin): def __init__(self, info=None): """ @@ -79,7 +55,7 @@ class Plugin(models.Plugin): exp = case['expected'] if not isinstance(exp, list): exp = [exp] - check_template(res, exp) + utils.check_template(res, exp) for r in res: r.validate() @@ -282,6 +258,8 @@ def load_plugins(folders, loader=load_plugin): plugins = {} for search_folder in folders: for root, dirnames, filenames in os.walk(search_folder): + # Do not look for plugins in hidden or special folders + dirnames[:] = [d for d in dirnames if d[0] not in ['.', '_']] for filename in fnmatch.filter(filenames, '*.senpy'): name, plugin = loader(root, filename) if plugin and name: diff --git a/senpy/utils.py b/senpy/utils.py new file mode 100644 index 0000000..6dae8c4 --- /dev/null +++ b/senpy/utils.py @@ -0,0 +1,25 @@ +from . import models + + +def check_template(indict, template): + if isinstance(template, dict) and isinstance(indict, dict): + for k, v in template.items(): + if k not in indict: + return '{} not in {}'.format(k, indict) + check_template(indict[k], v) + elif isinstance(template, list) and isinstance(indict, list): + if len(indict) != len(template): + raise models.Error('Different size for {} and {}'.format(indict, template)) + for e in template: + found = False + for i in indict: + try: + check_template(i, e) + found = True + except models.Error as ex: + continue + if not found: + raise models.Error('{} not found in {}'.format(e, indict)) + else: + if indict != template: + raise models.Error('{} and {} are different'.format(indict, template)) diff --git a/tests/test_blueprints.py b/tests/test_blueprints.py index 78b22ce..1e1cd9a 100644 --- a/tests/test_blueprints.py +++ b/tests/test_blueprints.py @@ -17,17 +17,19 @@ def parse_resp(resp): class BlueprintsTest(TestCase): - def setUp(self): - self.app = Flask("test_extensions") - self.app.debug = False - self.client = self.app.test_client() - self.senpy = Senpy() - self.senpy.init_app(self.app) - self.dir = os.path.join(os.path.dirname(__file__), "..") - self.senpy.add_folder(self.dir) - self.senpy.activate_plugin("Dummy", sync=True) - self.senpy.activate_plugin("DummyRequired", sync=True) - self.senpy.default_plugin = 'Dummy' + @classmethod + def setUpClass(cls): + """Set up only once, and re-use in every individual test""" + cls.app = Flask("test_extensions") + cls.app.debug = False + cls.client = cls.app.test_client() + cls.senpy = Senpy() + cls.senpy.init_app(cls.app) + cls.dir = os.path.join(os.path.dirname(__file__), "..") + cls.senpy.add_folder(cls.dir) + cls.senpy.activate_plugin("Dummy", sync=True) + cls.senpy.activate_plugin("DummyRequired", sync=True) + cls.senpy.default_plugin = 'Dummy' def assertCode(self, resp, code): self.assertEqual(resp.status_code, code) diff --git a/tests/test_plugins.py b/tests/test_plugins.py index b379cb9..0108194 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -33,7 +33,6 @@ class PluginsTest(TestCase): def tearDown(self): if os.path.exists(self.shelf_dir): shutil.rmtree(self.shelf_dir) - if os.path.isfile(self.shelf_file): os.remove(self.shelf_file) @@ -51,26 +50,29 @@ class PluginsTest(TestCase): def test_shelf(self): ''' A shelf is created and the value is stored ''' + newfile = self.shelf_file + "new" a = ShelfDummyPlugin(info={ 'name': 'shelve', 'version': 'test', - 'shelf_file': self.shelf_file + 'shelf_file': newfile }) assert a.sh == {} a.activate() assert a.sh == {'counter': 0} - assert a.shelf_file == self.shelf_file + assert a.shelf_file == newfile a.sh['a'] = 'fromA' assert a.sh['a'] == 'fromA' a.save() - sh = pickle.load(open(self.shelf_file, 'rb')) + sh = pickle.load(open(newfile, 'rb')) assert sh['a'] == 'fromA' def test_dummy_shelf(self): + with open(self.shelf_file, 'wb') as f: + pickle.dump({'counter': 99}, f) a = ShelfDummyPlugin(info={ 'name': 'DummyShelf', 'shelf_file': self.shelf_file, @@ -80,9 +82,13 @@ class PluginsTest(TestCase): assert a.shelf_file == self.shelf_file res1 = a.analyse(input=1) - assert res1.entries[0].nif__isString == 1 - res2 = a.analyse(input=1) - assert res2.entries[0].nif__isString == 2 + assert res1.entries[0].nif__isString == 100 + a.deactivate() + del a + + with open(self.shelf_file, 'rb') as f: + sh = pickle.load(f) + assert sh['counter'] == 100 def test_corrupt_shelf(self): ''' Reusing the values of a previous shelf '''