summaryrefslogtreecommitdiff
path: root/test/test_registry.py
diff options
context:
space:
mode:
authorLaurent Peuch <cortex@worlddomination.be>2020-03-20 14:18:08 +0100
committerLaurent Peuch <cortex@worlddomination.be>2020-03-20 14:18:08 +0100
commit2f92ba46d9801839063d940dfcf1f0d46c576b9d (patch)
tree171f7e33b04c3a60392d5279de175db3ef6243e4 /test/test_registry.py
parentdb91eae86a35dabbfd5986a1b1a10696ae3749ed (diff)
downloadlogilab-common-2f92ba46d9801839063d940dfcf1f0d46c576b9d.tar.gz
[tox] move to pytest
Diffstat (limited to 'test/test_registry.py')
-rw-r--r--test/test_registry.py220
1 files changed, 220 insertions, 0 deletions
diff --git a/test/test_registry.py b/test/test_registry.py
new file mode 100644
index 0000000..4d4104b
--- /dev/null
+++ b/test/test_registry.py
@@ -0,0 +1,220 @@
+# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of Logilab-Common.
+#
+# Logilab-Common is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# Logilab-Common is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with Logilab-Common. If not, see <http://www.gnu.org/licenses/>.
+"""unit tests for selectors mechanism"""
+
+import gc
+import logging
+import os.path as osp
+import sys
+from operator import eq, lt, le, gt
+from contextlib import contextmanager
+import warnings
+
+logging.basicConfig(level=logging.ERROR)
+
+from logilab.common.testlib import TestCase, unittest_main
+
+from logilab.common.registry import *
+
+
+class _1_(Predicate):
+ def __call__(self, *args, **kwargs):
+ return 1
+
+class _0_(Predicate):
+ def __call__(self, *args, **kwargs):
+ return 0
+
+def _2_(*args, **kwargs):
+ return 2
+
+
+class SelectorsTC(TestCase):
+ def test_basic_and(self):
+ selector = _1_() & _1_()
+ self.assertEqual(selector(None), 2)
+ selector = _1_() & _0_()
+ self.assertEqual(selector(None), 0)
+ selector = _0_() & _1_()
+ self.assertEqual(selector(None), 0)
+
+ def test_basic_or(self):
+ selector = _1_() | _1_()
+ self.assertEqual(selector(None), 1)
+ selector = _1_() | _0_()
+ self.assertEqual(selector(None), 1)
+ selector = _0_() | _1_()
+ self.assertEqual(selector(None), 1)
+ selector = _0_() | _0_()
+ self.assertEqual(selector(None), 0)
+
+ def test_selector_and_function(self):
+ selector = _1_() & _2_
+ self.assertEqual(selector(None), 3)
+ selector = _2_ & _1_()
+ self.assertEqual(selector(None), 3)
+
+ def test_three_and(self):
+ selector = _1_() & _1_() & _1_()
+ self.assertEqual(selector(None), 3)
+ selector = _1_() & _0_() & _1_()
+ self.assertEqual(selector(None), 0)
+ selector = _0_() & _1_() & _1_()
+ self.assertEqual(selector(None), 0)
+
+ def test_three_or(self):
+ selector = _1_() | _1_() | _1_()
+ self.assertEqual(selector(None), 1)
+ selector = _1_() | _0_() | _1_()
+ self.assertEqual(selector(None), 1)
+ selector = _0_() | _1_() | _1_()
+ self.assertEqual(selector(None), 1)
+ selector = _0_() | _0_() | _0_()
+ self.assertEqual(selector(None), 0)
+
+ def test_composition(self):
+ selector = (_1_() & _1_()) & (_1_() & _1_())
+ self.assertTrue(isinstance(selector, AndPredicate))
+ self.assertEqual(len(selector.selectors), 4)
+ self.assertEqual(selector(None), 4)
+ selector = (_1_() & _0_()) | (_1_() & _1_())
+ self.assertTrue(isinstance(selector, OrPredicate))
+ self.assertEqual(len(selector.selectors), 2)
+ self.assertEqual(selector(None), 2)
+
+ def test_search_selectors(self):
+ sel = _1_()
+ self.assertIs(sel.search_selector(_1_), sel)
+ csel = AndPredicate(sel, Predicate())
+ self.assertIs(csel.search_selector(_1_), sel)
+ csel = AndPredicate(Predicate(), sel)
+ self.assertIs(csel.search_selector(_1_), sel)
+ self.assertIs(csel.search_selector((AndPredicate, OrPredicate)), csel)
+ self.assertIs(csel.search_selector((OrPredicate, AndPredicate)), csel)
+ self.assertIs(csel.search_selector((_1_, _0_)), sel)
+ self.assertIs(csel.search_selector((_0_, _1_)), sel)
+
+ def test_inplace_and(self):
+ selector = _1_()
+ selector &= _1_()
+ selector &= _1_()
+ self.assertEqual(selector(None), 3)
+ selector = _1_()
+ selector &= _0_()
+ selector &= _1_()
+ self.assertEqual(selector(None), 0)
+ selector = _0_()
+ selector &= _1_()
+ selector &= _1_()
+ self.assertEqual(selector(None), 0)
+ selector = _0_()
+ selector &= _0_()
+ selector &= _0_()
+ self.assertEqual(selector(None), 0)
+
+ def test_inplace_or(self):
+ selector = _1_()
+ selector |= _1_()
+ selector |= _1_()
+ self.assertEqual(selector(None), 1)
+ selector = _1_()
+ selector |= _0_()
+ selector |= _1_()
+ self.assertEqual(selector(None), 1)
+ selector = _0_()
+ selector |= _1_()
+ selector |= _1_()
+ self.assertEqual(selector(None), 1)
+ selector = _0_()
+ selector |= _0_()
+ selector |= _0_()
+ self.assertEqual(selector(None), 0)
+
+ def test_wrap_selectors(self):
+ class _temp_(Predicate):
+ def __call__(self, *args, **kwargs):
+ return 0
+ del _temp_ # test weakref
+ s1 = _1_() & _1_()
+ s2 = _1_() & _0_()
+ s3 = _0_() & _1_()
+ gc.collect()
+ self.count = 0
+ def decorate(f, self=self):
+ def wrapper(*args, **kwargs):
+ self.count += 1
+ return f(*args, **kwargs)
+ return wrapper
+ wrap_predicates(decorate)
+ self.assertEqual(s1(None), 2)
+ self.assertEqual(s2(None), 0)
+ self.assertEqual(s3(None), 0)
+ self.assertEqual(self.count, 8)
+
+@contextmanager
+def prepended_syspath(path):
+ sys.path.insert(0, path)
+ yield
+ sys.path = sys.path[1:]
+
+class RegistryStoreTC(TestCase):
+
+ def test_autoload(self):
+ store = RegistryStore()
+ store.setdefault('zereg')
+ with prepended_syspath(self.datadir):
+ with warnings.catch_warnings(record=True) as warns:
+ store.register_objects([self.datapath('regobjects.py'),
+ self.datapath('regobjects2.py')])
+ self.assertIn('[logilab.common] use register_modnames() instead',
+ [str(w.message) for w in warns])
+ self.assertEqual(['zereg'], list(store.keys()))
+ self.assertEqual(set(('appobject1', 'appobject2', 'appobject3')),
+ set(store['zereg']))
+
+ def test_autoload_modnames(self):
+ store = RegistryStore()
+ store.setdefault('zereg')
+ with prepended_syspath(self.datadir):
+ store.register_modnames(['regobjects', 'regobjects2'])
+ self.assertEqual(['zereg'], list(store.keys()))
+ self.assertEqual(set(('appobject1', 'appobject2', 'appobject3')),
+ set(store['zereg']))
+
+
+class RegistrableInstanceTC(TestCase):
+
+ def test_instance_modulename(self):
+ with warnings.catch_warnings(record=True) as warns:
+ obj = RegistrableInstance()
+ self.assertEqual(obj.__module__, 'test_registry')
+ self.assertIn('instantiate RegistrableInstance with __module__=__name__',
+ [str(w.message) for w in warns])
+ # no inheritance
+ obj = RegistrableInstance(__module__=__name__)
+ self.assertEqual(obj.__module__, 'test_registry')
+ # with inheritance from another python file
+ with prepended_syspath(self.datadir):
+ from regobjects2 import instance, MyRegistrableInstance
+ instance2 = MyRegistrableInstance(__module__=__name__)
+ self.assertEqual(instance.__module__, 'regobjects2')
+ self.assertEqual(instance2.__module__, 'test_registry')
+
+
+if __name__ == '__main__':
+ unittest_main()