aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Harder <radhermit@gmail.com>2021-03-04 13:41:41 -0700
committerTim Harder <radhermit@gmail.com>2021-03-04 13:44:52 -0700
commit00684d51abf632310b58e5ed56b0ed61d9eeeb3d (patch)
tree19e965b2eb1ba5bc87ee5227dbb571a243a0ac56 /tests/restrictions
parentcoverage: minor config update (diff)
downloadpkgcore-00684d51abf632310b58e5ed56b0ed61d9eeeb3d.tar.gz
pkgcore-00684d51abf632310b58e5ed56b0ed61d9eeeb3d.tar.bz2
pkgcore-00684d51abf632310b58e5ed56b0ed61d9eeeb3d.zip
tests: move to repo root dir
Diffstat (limited to 'tests/restrictions')
-rw-r--r--tests/restrictions/__init__.py0
-rw-r--r--tests/restrictions/test_boolean.py165
-rw-r--r--tests/restrictions/test_delegated.py40
-rw-r--r--tests/restrictions/test_packages.py198
-rw-r--r--tests/restrictions/test_restriction.py100
-rw-r--r--tests/restrictions/test_util.py32
-rw-r--r--tests/restrictions/test_values.py334
7 files changed, 869 insertions, 0 deletions
diff --git a/tests/restrictions/__init__.py b/tests/restrictions/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/restrictions/__init__.py
diff --git a/tests/restrictions/test_boolean.py b/tests/restrictions/test_boolean.py
new file mode 100644
index 000000000..5f998f048
--- /dev/null
+++ b/tests/restrictions/test_boolean.py
@@ -0,0 +1,165 @@
+from snakeoil.test import TestCase
+
+from pkgcore.restrictions import boolean, restriction
+
+true = restriction.AlwaysBool(node_type='foo', negate=True)
+false = restriction.AlwaysBool(node_type='foo', negate=False)
+
+
+class AlwaysForcableBool(boolean.base):
+
+ __slots__ = ()
+
+ def force_True(self, action, *args):
+ yield True
+
+ match = force_False = force_True
+
+
+class base:
+
+ kls = None
+
+ def test_invalid_restrictions(self):
+ self.assertRaises(TypeError, self.kls, 42, node_type='foo')
+ base = self.kls(node_type='foo')
+ self.assertRaises(TypeError, base.add_restriction, 42)
+ self.assertRaises(TypeError, base.add_restriction)
+
+ def test_init_finalize(self):
+ final = self.kls(true, node_type='foo', finalize=True)
+ # since it becomes a tuple, throws a AttributeError
+ self.assertRaises(TypeError, final.add_restriction, false)
+
+ final = self.kls(true, node_type='foo')
+ # since it becomes a tuple, throws a AttributeError
+ self.assertRaises(TypeError, final.add_restriction, false)
+
+ def test_finalize(self):
+ base = self.kls(true, node_type='foo', finalize=False)
+ base.add_restriction(false)
+ base.finalize()
+ self.assertRaises(TypeError, base.add_restriction, true)
+
+ def test_change_restrictions(self):
+ base = self.kls(true, false)
+ assert self.kls(false, true) == base.change_restrictions(false, true)
+ assert self.kls(false, true) != base.change_restrictions(false, true, negate=True)
+ assert self.kls(false, true, negate=True) == base.change_restrictions(false, true, negate=True)
+
+ def test_add_restriction(self):
+ self.assertRaises(TypeError,
+ self.kls(true, finalize=True).add_restriction, false)
+ self.assertRaises(TypeError,
+ self.kls(node_type='foon').add_restriction, false)
+ k = self.kls(finalize=False)
+ k.add_restriction(false)
+ assert k.restrictions == [false]
+
+ # TODO total_len? what does it do?
+
+class BaseTest(base, TestCase):
+
+ kls = boolean.base
+
+ def test_base(self):
+ base = self.kls(true, false, node_type='foo')
+ assert len(base) == 2
+ assert list(base) == [true, false]
+ self.assertRaises(NotImplementedError, base.match, false)
+ # TODO is the signature for these correct?
+ self.assertRaises(NotImplementedError, base.force_False, false)
+ self.assertRaises(NotImplementedError, base.force_True, false)
+ self.assertIdentical(base[1], false)
+
+
+# TODO these tests are way too limited
+class AndRestrictionTest(base, TestCase):
+
+ kls = boolean.AndRestriction
+
+ def test_match(self):
+ assert self.kls(true, true, node_type='foo').match(None)
+ assert not self.kls(false, true, true, node_type='foo').match(None)
+ assert not self.kls(true, false, true, node_type='foo').match(None)
+
+ def test_negate_match(self):
+ assert self.kls(false, true, node_type='foo', negate=True).match(None)
+ assert self.kls(true, false, node_type='foo', negate=True).match(None)
+ assert self.kls(false, false, node_type='foo', negate=True).match(None)
+ assert not self.kls(true, true, node_type='foo', negate=True).match(None)
+
+ def test_dnf_solutions(self):
+ assert self.kls(true, true).dnf_solutions() == [[true, true]]
+ assert self.kls(self.kls(true, true), true).dnf_solutions() == [[true, true, true]]
+ assert (list(map(set, self.kls(
+ true, true,
+ boolean.OrRestriction(false, true)).dnf_solutions())) ==
+ [set([true, true, false]), set([true, true, true])])
+ assert self.kls().dnf_solutions() == [[]]
+
+ def test_cnf_solutions(self):
+ assert self.kls(true, true).cnf_solutions() == [[true], [true]]
+ assert self.kls(self.kls(true, true), true).cnf_solutions() == [[true], [true], [true]]
+ assert (list(self.kls(
+ true, true,
+ boolean.OrRestriction(false, true)).cnf_solutions()) ==
+ list([[true], [true], [false, true]]))
+ assert self.kls().cnf_solutions() == []
+
+
+class OrRestrictionTest(base, TestCase):
+
+ kls = boolean.OrRestriction
+
+ def test_match(self):
+ assert self.kls(true, true, node_type='foo').match(None)
+ assert self.kls(false, true, false, node_type='foo').match(None)
+ assert self.kls(true, false, false, node_type='foo').match(None)
+ assert self.kls(false, false, true, node_type='foo').match(None)
+ assert not self.kls(false, false, node_type='foo').match(None)
+
+ def test_negate_match(self):
+ for x in ((true, false), (false, true), (true, true)):
+ assert not self.kls(node_type='foo', negate=True, *x).match(None)
+ assert self.kls(false, false, node_type='foo', negate=True).match(None)
+
+ def test_dnf_solutions(self):
+ assert self.kls(true, true).dnf_solutions() == [[true], [true]]
+ assert (list(map(set, self.kls(
+ true, true,
+ boolean.AndRestriction(false, true)).dnf_solutions())) ==
+ list(map(set, [[true], [true], [false, true]])))
+ assert self.kls(self.kls(true, false), true).dnf_solutions() == [[true], [false], [true]]
+ assert self.kls().dnf_solutions() == [[]]
+
+ def test_cnf_solutions(self):
+ assert self.kls(true, true).cnf_solutions() == [[true, true]]
+ assert ([set(x) for x in self.kls(
+ true, true,
+ boolean.AndRestriction(false, true)).cnf_solutions()] ==
+ [set(x) for x in [[true, false], [true, true]]])
+
+ assert ([set(x) for x in self.kls(self.kls(
+ true, true,
+ boolean.AndRestriction(false, true))).cnf_solutions()] ==
+ [set(x) for x in [[true, false], [true, true]]])
+
+ assert (set(self.kls(
+ self.kls(true, false),
+ true).cnf_solutions()[0]) ==
+ set([true, false, true]))
+
+ assert self.kls().cnf_solutions() == []
+
+
+class JustOneRestrictionTest(base, TestCase):
+
+ kls = boolean.JustOneRestriction
+
+ def test_match(self):
+ assert self.kls(true, false, node_type='foo').match(None)
+ assert self.kls(false, true, false, node_type='foo').match(None)
+ assert not self.kls(false, false, node_type='foo').match(None)
+ assert not self.kls(true, false, true, node_type='foo').match(None)
+ assert not self.kls(true, true, true, node_type='foo').match(None)
diff --git a/tests/restrictions/test_delegated.py b/tests/restrictions/test_delegated.py
new file mode 100644
index 000000000..e392707ec
--- /dev/null
+++ b/tests/restrictions/test_delegated.py
@@ -0,0 +1,40 @@
+from pkgcore.restrictions.delegated import delegate
+from pkgcore.test import TestRestriction
+
+
+class Test_delegate(TestRestriction):
+
+ kls = delegate
+
+ def test_it(self):
+ self.assertRaises(TypeError, self.kls, None, None)
+ y = True
+ l = []
+ def f(x, mode):
+ l.append(mode)
+ if mode == 'force_False':
+ return not y
+ return y
+
+ for negated in (False, True):
+ def assertIt(got, expected):
+ self.assertEqual(
+ got, expected,
+ msg=f"got={got!r}, expected={expected!r}, negate={negated!r}")
+ y = True
+ l[:] = []
+ o = self.kls(f, negate=negated)
+ self.assertMatches(o, [None], negated=negated)
+
+ y = False
+ self.assertNotMatches(o, [None], negated=negated)
+
+ if negated:
+ assertIt(l, ['match', 'force_False', 'force_True',
+ 'match', 'force_False', 'force_True'])
+ else:
+ assertIt(l, ['match', 'force_True', 'force_False',
+ 'match', 'force_True', 'force_False'])
+
+ def test_caching(self):
+ self.assertFalse(self.kls.inst_caching, False)
diff --git a/tests/restrictions/test_packages.py b/tests/restrictions/test_packages.py
new file mode 100644
index 000000000..b716073e1
--- /dev/null
+++ b/tests/restrictions/test_packages.py
@@ -0,0 +1,198 @@
+from snakeoil.mappings import AttrAccessible
+
+from pkgcore import log
+from pkgcore.restrictions import packages, values
+from pkgcore.test import (TestCase, TestRestriction, callback_logger,
+ malleable_obj, silence_logging)
+
+
+class AlwaysSelfIntersect(values.base):
+ def intersect(self, other):
+ return self
+
+ __hash__ = object.__hash__
+
+
+class TestPackageRestriction(TestRestriction):
+
+ if packages.PackageRestriction is packages.PackageRestriction:
+ kls = packages.PackageRestriction
+ else:
+ class kls(packages.PackageRestriction,
+ packages.PackageRestriction_mixin):
+ __slots__ = ()
+ __inst_caching__ = packages.PackageRestriction.__inst_caching__
+
+ kls = staticmethod(kls)
+
+ @silence_logging(log.logging.root)
+ def test_matching(self):
+ strexact = values.StrExactMatch
+
+ args = malleable_obj(category="foon", package="dar")
+ self.assertMatches(self.kls("category", strexact("foon")), args)
+ self.assertMatches(self.kls("package", strexact("dar")), args)
+ self.assertNotMatches(self.kls("package", strexact("dar"), negate=True),
+ args)
+ self.assertNotMatches(self.kls("package", strexact("foon")), args)
+
+ self.assertMatches(self.kls("package", strexact("foon"), negate=True),
+ args)
+ excepts = []
+ # no msg should be thrown, it wasn't an unexpected exception
+
+ log.logging.root.addHandler(callback_logger(excepts.append))
+ self.assertNotMatches(self.kls("foon", AlwaysSelfIntersect), args)
+ self.assertFalse(excepts)
+
+ self.assertMatches(self.kls("foon", AlwaysSelfIntersect, negate=True),
+ args)
+ self.assertFalse(excepts)
+
+ class foo:
+ def __getattr__(self, attr):
+ if attr.startswith("exc"):
+ raise exceptions_d.get(attr[4:], None)()
+ raise AttributeError("monkey lover")
+
+ exceptions_d = {"KeyboardInterrupt":KeyboardInterrupt,
+ "RuntimeError":RuntimeError, "SystemExit":SystemExit}
+
+ for mode in ("match", "force_True", "force_False"):
+ excepts[:] = []
+ self.assertRaises(AttributeError,
+ getattr(self.kls("foon", AlwaysSelfIntersect), mode),
+ foo())
+ self.assertEqual(
+ len(excepts), 1,
+ msg=f"expected one exception, got {excepts!r}")
+
+ # ensure various exceptions are passed through
+ for k in (KeyboardInterrupt, RuntimeError, SystemExit):
+ self.assertRaises(
+ k,
+ getattr(self.kls(f"exc_{k.__name__}", AlwaysSelfIntersect), mode),
+ foo())
+
+ # check that it only does string comparison in exception catching.
+ class foo:
+ def __cmp__(self, other):
+ raise TypeError
+
+ def __getattr__(self, attr):
+ raise AttributeError(self, attr)
+
+ self.assertFalse(self.kls("foon", AlwaysSelfIntersect).match(foo()))
+
+ def test_attr(self):
+ self.assertEqual(self.kls('val', values.AlwaysTrue).attr,
+ 'val')
+ self.assertEqual(self.kls('val.dar', values.AlwaysTrue).attr,
+ 'val.dar')
+ self.assertEqual(self.kls('val', values.AlwaysTrue).attrs,
+ ('val',))
+ self.assertEqual(self.kls('val.dar', values.AlwaysTrue).attrs,
+ ('val.dar',))
+
+ def test_eq(self):
+ self.assertEqual(
+ self.kls('one', values.AlwaysTrue),
+ self.kls('one', values.AlwaysTrue))
+ self.assertNotEqual(
+ self.kls('one', values.AlwaysTrue),
+ self.kls('one', values.AlwaysTrue, negate=True))
+ self.assertNotEqual(
+ self.kls('one', values.AlwaysTrue),
+ self.kls('two', values.AlwaysTrue))
+ self.assertNotEqual(
+ self.kls('one', values.AlwaysTrue, negate=True),
+ self.kls('one', values.AlwaysFalse, negate=True))
+
+ def test_hash(self):
+ inst = self.kls('one.dar', AlwaysSelfIntersect())
+ hash(inst)
+
+
+class values_callback(values.base):
+
+ __slots__ = ("callback",)
+
+ def __init__(self, callback):
+ object.__setattr__(self, 'callback', callback)
+
+ def match(self, val):
+ return self.callback((None, val))
+
+ def force_True(self, pkg, attr, val):
+ return self.callback((True, pkg, attr, val))
+
+ def force_False(self, pkg, attr, val):
+ return self.callback((False, pkg, attr, val))
+
+
+class TestPackageRestrictionMulti(TestCase):
+
+ if packages.PackageRestriction is packages.PackageRestriction:
+ kls = packages.PackageRestrictionMulti
+ else:
+ class kls(packages.PackageRestrictionMulti,
+ packages.PackageRestrictionMulti_mixin):
+ __slots__ = ()
+ __inst_caching__ = packages.PackageRestrictionMulti.__inst_caching__
+
+ kls = staticmethod(kls)
+
+ def test_attr(self):
+ o = self.kls(("asdf.far", "repo"), values.AlwaysTrue)
+ self.assertEqual(o.attrs, ("asdf.far", "repo"))
+ self.assertEqual(o.attr, None)
+
+ def test_values(self):
+ l = []
+ def f(*args):
+ self.assertLen(args, 1)
+ l.append(args[0])
+ return True
+
+ o = self.kls(("asdf.far", "repo"), values_callback(f))
+
+ pkg = AttrAccessible()
+ o.match(pkg)
+ self.assertFalse(l)
+
+ pkg['repo'] = 1
+ o.match(pkg)
+ self.assertFalse(l)
+
+ pkg['asdf'] = AttrAccessible(far=2)
+ o.match(pkg)
+ self.assertEqual(l, [(None, [2,1],)])
+
+ l[:] = []
+ o.force_True(pkg)
+ self.assertEqual(l, [(True, pkg, ('asdf.far', 'repo'), [2,1],)])
+
+ l[:] = []
+ o.force_False(pkg)
+ self.assertEqual(l, [(False, pkg, ('asdf.far', 'repo'), [2,1],)])
+
+
+class ConditionalTest(TestCase):
+
+ def test_eq(self):
+ p = (packages.PackageRestriction('one', values.AlwaysTrue),)
+ p2 = (packages.PackageRestriction('one', values.AlwaysFalse),)
+ v = values.AlwaysTrue
+ v2 = values.AlwaysFalse
+ self.assertEqual(
+ packages.Conditional('use', v, p),
+ packages.Conditional('use', v, p))
+ self.assertNotEqual(
+ packages.Conditional('use', v2, p),
+ packages.Conditional('use', v, p))
+ self.assertNotEqual(
+ packages.Conditional('use', v, p),
+ packages.Conditional('use', v, p2))
+ self.assertNotEqual(
+ packages.Conditional('use1', v, p),
+ packages.Conditional('use', v, p))
diff --git a/tests/restrictions/test_restriction.py b/tests/restrictions/test_restriction.py
new file mode 100644
index 000000000..03305bc77
--- /dev/null
+++ b/tests/restrictions/test_restriction.py
@@ -0,0 +1,100 @@
+from functools import partial
+
+from pkgcore.restrictions import restriction
+from pkgcore.test import TestRestriction
+
+
+class SillyBool(restriction.base):
+ """Extra stupid version of AlwaysBool to test base.force_{True,False}."""
+
+ __slots__ = ('negate',)
+
+ def __init__(self, negate=False):
+ object.__setattr__(self, 'negate', negate)
+
+ def match(self, *args, **kwargs):
+ return not self.negate
+
+
+class BaseTest(TestRestriction):
+
+ bool_kls = SillyBool
+
+ def test_base(self):
+ base = restriction.base()
+ self.assertEqual(len(base), 1)
+ # Just check repr and str do not raise
+ self.assertTrue(str(base))
+ self.assertTrue(repr(base))
+ self.assertTrue(hash(base))
+ self.assertRaises(NotImplementedError, base.match)
+
+ def test_it(self):
+ true = self.bool_kls(negate=False)
+ false = self.bool_kls(negate=True)
+ args = [None]
+
+ self.assertMatch(true, args[0])
+ self.assertForceTrue(true, args)
+ self.assertNotForceFalse(true, args)
+
+ self.assertNotMatch(false, args[0])
+ self.assertNotForceTrue(false, args)
+ self.assertForceFalse(false, args)
+
+
+class AlwaysBoolTest(TestRestriction):
+
+ bool_kls = partial(restriction.AlwaysBool, 'foo')
+
+ def test_true(self):
+ true_r = self.bool_kls(True)
+ false_r = self.bool_kls(False)
+ self.assertMatch(true_r, false_r)
+ self.assertForceTrue(true_r, false_r)
+ self.assertNotForceFalse(true_r, false_r)
+
+ self.assertNotMatch(false_r, true_r)
+ self.assertNotForceTrue(false_r, true_r)
+ self.assertForceFalse(false_r, true_r)
+
+ self.assertEqual(str(true_r), "always 'True'")
+ self.assertEqual(str(false_r), "always 'False'")
+ self.assertNotEqual(hash(true_r), hash(false_r))
+ self.assertEqual(hash(true_r),
+ hash(self.bool_kls(True)))
+ self.assertEqual(hash(false_r),
+ hash(self.bool_kls(False)))
+ self.assertEqual(true_r, self.bool_kls(True))
+ self.assertEqual(false_r, self.bool_kls(False))
+ self.assertNotEqual(true_r, false_r)
+
+
+class NoneMatch(restriction.base):
+
+ """Only matches None."""
+
+ __slots__ = ()
+
+ def match(self, val):
+ return val is None
+
+ def __repr__(self):
+ return '<NoneMatch>'
+
+ def __str__(self):
+ return 'NoneMatch'
+
+
+class AnyMatchTest(TestRestriction):
+
+ def test_basic(self):
+ for negate in (False, True):
+ inst = restriction.AnyMatch(NoneMatch(), 'spork', negate=negate)
+ self.assertMatch(inst, ['spork', None], negated=negate)
+ self.assertNotMatch(inst, ['spork'], negated=negate)
+ self.assertNotMatch(inst, (), negated=negate)
+
+ # just test these do not traceback
+ self.assertTrue(repr(inst))
+ self.assertTrue(str(inst))
diff --git a/tests/restrictions/test_util.py b/tests/restrictions/test_util.py
new file mode 100644
index 000000000..5e125d7e2
--- /dev/null
+++ b/tests/restrictions/test_util.py
@@ -0,0 +1,32 @@
+from snakeoil.test import TestCase
+
+from pkgcore.restrictions import packages, util, values
+
+
+class Test_collect_package_restrictions(TestCase):
+
+ def test_collect_all(self):
+ prs = [packages.PackageRestriction("category", values.AlwaysTrue)] * 10
+ self.assertEqual(
+ list(util.collect_package_restrictions(packages.AndRestriction(
+ packages.OrRestriction(), packages.AndRestriction(),
+ *prs))),
+ prs)
+
+ def test_collect_specific(self):
+ prs = {}
+ for x in ("category", "package", "version", "iuse"):
+ prs[x] = packages.PackageRestriction(x, values.AlwaysTrue)
+
+ r = packages.AndRestriction(
+ packages.OrRestriction(*prs.values()), packages.AlwaysTrue)
+ for k, v in prs.items():
+ self.assertEqual(
+ list(util.collect_package_restrictions(r, attrs=[k])),
+ [v])
+ r = packages.AndRestriction(packages.OrRestriction(
+ *prs.values()), *prs.values())
+ for k, v in prs.items():
+ self.assertEqual(
+ list(util.collect_package_restrictions(r, attrs=[k])),
+ [v] * 2)
diff --git a/tests/restrictions/test_values.py b/tests/restrictions/test_values.py
new file mode 100644
index 000000000..2571f45de
--- /dev/null
+++ b/tests/restrictions/test_values.py
@@ -0,0 +1,334 @@
+from snakeoil.test import TestCase
+
+from pkgcore.restrictions import values
+from pkgcore.test import TestRestriction
+
+
+class SillyBool(values.base):
+ """Extra stupid version of AlwaysBool to test base.force_{True,False}."""
+ def __init__(self, negate=False):
+ object.__setattr__(self, "negate", negate)
+
+ def match(self, something):
+ return not self.negate
+
+
+class BaseTest(TestRestriction):
+
+ def test_force(self):
+ self.assertMatches(SillyBool(negate=False), None, [None]*3)
+ self.assertNotMatches(SillyBool(negate=True), None, [None]*3)
+
+
+class GetAttrTest(TestRestriction):
+
+ """Test bits of GetAttrRestriction that differ from PackageRestriction."""
+
+ def test_force(self):
+ # TODO we could do with both more tests and a more powerful
+ # force_* implementation. This just tests if the function
+ # takes the right number of arguments.
+
+ # TODO test negate handling
+ succeeds = values.GetAttrRestriction('test', values.AlwaysTrue)
+ fails = values.GetAttrRestriction('test', values.AlwaysFalse)
+
+ class Dummy:
+ test = True
+
+ dummy = Dummy()
+
+ class FakePackage:
+ """XXX this is vastly too minimal."""
+ value = dummy
+
+ pkg = FakePackage()
+
+ args = [pkg, 'value', dummy]
+ self.assertForceTrue(succeeds, args)
+ self.assertNotForceFalse(succeeds, args)
+ self.assertNotForceTrue(fails, args)
+ self.assertForceFalse(fails, args)
+
+
+class StrRegexTest(TestRestriction):
+
+ kls = values.StrRegex
+
+ def test_match(self):
+ for negated in (False, True):
+ self.assertMatches(self.kls('foo.*r', match=True,
+ negate=negated),
+ 'foobar', [None, None, 'foobar'], negated=negated)
+ self.assertNotMatches(self.kls('foo.*r', match=True,
+ negate=negated),
+ 'afoobar', [None, None, 'afoobar'], negated=negated)
+
+ def test_search(self):
+ for negated in (False, True):
+ self.assertMatches(self.kls('foo.*r', negate=negated),
+ 'asdfoobar', [None, None, 'asdfoobar'], negated=negated)
+ self.assertNotMatches(self.kls('foo.*r', negate=negated),
+ 'afobar', [None, None, 'afobar'], negated=negated)
+
+ def test_case_sensitivity(self):
+ self.assertNotMatches(self.kls('foo'), 'FoO', ['FOo']*3)
+ self.assertMatches(self.kls('foo', False), 'FoO', ['fOo']*3)
+
+ def test_str(self):
+ assert 'search spork' == str(self.kls('spork'))
+ assert 'not search spork' == str(self.kls('spork', negate=True))
+ assert 'match spork' == str(self.kls('spork', match=True))
+ assert 'not match spork' == str(self.kls('spork', match=True, negate=True))
+
+ def test_repr(self):
+ for restr, string in [
+ (self.kls('spork'), "<StrRegex 'spork' search @"),
+ (self.kls('spork', match=True),
+ "<StrRegex 'spork' match @"),
+ (self.kls('spork', negate=True),
+ "<StrRegex 'spork' negated search @"),
+ ]:
+ self.assertTrue(repr(restr).startswith(string), (restr, string))
+
+
+
+class TestStrExactMatch(TestRestriction):
+
+ if values.StrExactMatch is values.StrExactMatch:
+ kls = values.StrExactMatch
+ else:
+ class kls(values.StrExactMatch, values.base):
+ __slots__ = ()
+ __inst_caching__ = True
+
+ intersect = values._StrExact_intersect
+ __repr__ = values._StrExact__repr__
+ __str__ = values._StrExact__str__
+
+ kls = staticmethod(kls)
+
+ def test_case_sensitive(self):
+ for negated in (False, True):
+ self.assertMatches(self.kls('package', negate=negated),
+ 'package', ['package']*3, negated=negated)
+ self.assertNotMatches(self.kls('Package', negate=negated),
+ 'package', ['package']*3, negated=negated)
+
+ def test_case_insensitive(self):
+ for negated in (False, True):
+ # note that we explicitly test True/1, and False/0
+ # we test 1/0, since bool protocol is supported for those kwds-
+ # thus we verify it, more specifically we verify the cpy
+ # support.
+ self.assertMatches(self.kls('package', case_sensitive=True,
+ negate=negated),
+ 'package', ['package']*3, negated=negated)
+ self.assertMatches(self.kls('package', case_sensitive=1,
+ negate=negated),
+ 'package', ['package']*3, negated=negated)
+ self.assertMatches(self.kls('Package', case_sensitive=False,
+ negate=negated),
+ 'package', ['package']*3, negated=negated)
+ self.assertMatches(self.kls('Package', case_sensitive=0,
+ negate=negated),
+ 'package', ['package']*3, negated=negated)
+
+ def test__eq__(self):
+ for negate in (True, False):
+ assert self.kls("rsync", negate=negate) == self.kls("rsync", negate=negate)
+ for x in "Ca":
+ assert self.kls("rsync", negate=negate) != self.kls("rsyn"+x, negate=negate)
+ assert (
+ self.kls("Rsync", case_sensitive=False, negate=negate) ==
+ self.kls("rsync", case_sensitive=False, negate=negate))
+
+
+class TestStrGlobMatch(TestRestriction):
+
+ kls = values.StrGlobMatch
+
+ def test_matching(self):
+ for negated in (True, False):
+ self.assertMatches(self.kls('pack', negate=negated),
+ 'package', ['package']*3, negated=negated)
+ self.assertNotMatches(self.kls('pack', negate=negated),
+ 'apack', ['apack']*3, negated=negated)
+ # case sensitive...
+ self.assertMatches(self.kls('pAcK', case_sensitive=False,
+ negate=negated),
+ 'pack', ['pack']*3, negated=negated)
+ self.assertNotMatches(self.kls('pAcK',
+ case_sensitive=True, negate=negated),
+ 'pack', ['pack']*3, negated=negated)
+
+ # check prefix.
+ self.assertMatches(self.kls('pAck', case_sensitive=False,
+ prefix=True, negate=negated),
+ 'packa', ['packa']*3, negated=negated)
+
+ self.assertNotMatches(self.kls('pack', prefix=False,
+ negate=negated),
+ 'apacka', ['apacka']*3, negated=negated)
+
+ self.assertMatches(self.kls('pack', prefix=False,
+ negate=negated),
+ 'apack', ['apack']*3, negated=negated)
+
+ # daft, but verifies it's not doing contains.
+ self.assertNotMatches(self.kls('pack', prefix=False,
+ negate=negated),
+ 'apacka', ['apacka']*3, negated=negated)
+
+ self.assertNotMatches(self.kls('pack', prefix=False,
+ case_sensitive=False, negate=negated),
+ 'aPacka', ['aPacka']*3, negated=negated)
+
+ def test__eq__(self):
+ self.assertFalse(
+ self.kls("rsync", prefix=False) ==
+ self.kls("rsync", prefix=True))
+ for negate in (True, False):
+ assert self.kls("rsync", negate=negate) == self.kls("rsync", negate=negate)
+ for x in "Ca":
+ self.assertNotEqual(
+ self.kls("rsync", negate=negate),
+ self.kls("rsyn"+x, negate=negate))
+ self.assertNotEqual(
+ self.kls("Rsync", case_sensitive=False, negate=negate),
+ self.kls("rsync", case_sensitive=True, negate=negate))
+ self.assertNotEqual(
+ self.kls("rsync", case_sensitive=False, negate=negate),
+ self.kls("rsync", case_sensitive=True, negate=negate))
+ self.assertNotEqual(
+ self.kls("rsync", case_sensitive=False, negate=negate),
+ self.kls("rsync", case_sensitive=True, negate=not negate))
+ self.assertNotEqual(
+ self.kls("rsync", negate=True),
+ self.kls("rsync", negate=False))
+
+
+class TestEqualityMatch(TestRestriction):
+
+ kls = staticmethod(values.EqualityMatch)
+
+ def test_match(self):
+ for x, y, ret in (("asdf", "asdf", True), ("asdf", "fdsa", False),
+ (1, 1, True), (1,2, False),
+ (list(range(2)), list(range(2)), True),
+ (list(range(2)), reversed(list(range(2))), False),
+ (True, True, True),
+ (True, False, False),
+ (False, True, False)):
+ for negated in (True, False):
+ self.assertMatches(self.kls(x, negate=negated),
+ y, [y]*3, negated=(ret ^ (not negated)))
+
+ def test__eq__(self):
+ for negate in (True, False):
+ assert self.kls("asdf", negate=negate) == self.kls("asdf", negate=negate)
+ self.assertNotEqual(
+ self.kls(1, negate=negate),
+ self.kls(2, negate=negate))
+ self.assertNotEqual(
+ self.kls("asdf", negate=True),
+ self.kls("asdf", negate=False))
+
+ def test__hash__(self):
+ def f(*args, **kwds):
+ return hash(self.kls(*args, **kwds))
+ assert f("dar") == f("dar")
+ assert f("dar") == f("dar", negate=False)
+ assert f("dar", negate=True) != f("dar", negate=False)
+ assert f("dar", negate=True) == f("dar", negate=True)
+ assert f("dar") != f("dar2")
+ assert f("dar", negate=True) != f("dar2")
+
+
+class TestContainmentMatch(TestRestriction):
+
+ kls = values.ContainmentMatch
+
+ def test_match(self):
+ for x, y, ret in (
+ (list(range(10)), list(range(10)), True),
+ (list(range(10)), [], False),
+ (list(range(10)), set(range(10)), True),
+ (set(range(10)), list(range(10)), True)):
+
+ for negated in (False, True):
+ self.assertMatches(self.kls(negate=negated,
+ disable_inst_caching=True, *x),
+ y, [y]*3, negated=(ret == negated))
+
+ for negated in (False, True):
+ # intentionally differing for the force_* args; slips in
+ # an extra data set for testing.
+ self.assertMatches(self.kls(all=True, negate=negated, *range(10)),
+ list(range(20)), [list(range(10))]*3, negated=negated)
+ self.assertNotMatches(self.kls(all=True, negate=negated, *range(10)),
+ list(range(5)), [list(range(5))]*3, negated=negated)
+
+ self.assertNotMatches(self.kls("asdf"), "fdsa", ["fdas"]*3)
+ self.assertMatches(self.kls("asdf"), "asdf", ["asdf"]*3)
+ self.assertMatches(self.kls("asdf"), "asdffdsa", ["asdffdsa"]*3)
+ self.assertMatches(self.kls("b"), "aba", ["aba"]*3)
+
+ def test__eq__(self):
+ for negate in (True, False):
+ assert self.kls(negate=negate, *range(100)) == self.kls(negate=negate, *range(100)), \
+ f"range(100), negate={negate}"
+ assert self.kls(1, negate=not negate) != self.kls(1, negate=negate)
+ assert (
+ self.kls(1, 2, 3, all=True, negate=negate) ==
+ self.kls(1, 2, 3, all=True, negate=negate))
+ assert (
+ self.kls(1, 2, all=True, negate=negate) !=
+ self.kls(1, 2, 3, all=True, negate=negate))
+ assert (
+ self.kls(1, 2, 3, all=False, negate=negate) !=
+ self.kls(1, 2, 3, all=True, negate=negate))
+
+
+class FlatteningRestrictionTest(TestCase):
+
+ def test_basic(self):
+ for negate in (False, True):
+ inst = values.FlatteningRestriction(
+ tuple, values.AnyMatch(values.EqualityMatch(None)),
+ negate=negate)
+ assert not negate == inst.match([7, 8, [9, None]])
+ assert negate == inst.match([7, 8, (9, None)])
+ # Just check this does not raise
+ self.assertTrue(str(inst))
+ self.assertTrue(repr(inst))
+
+
+class FunctionRestrictionTest(TestCase):
+
+ def test_basic(self):
+
+ def yes(val):
+ return True
+ def no(val):
+ return False
+
+ for negate in (False, True):
+ yes_restrict = values.FunctionRestriction(yes, negate=negate)
+ no_restrict = values.FunctionRestriction(no, negate=negate)
+ assert not negate == yes_restrict.match(7)
+ assert negate == no_restrict.match(7)
+ for restrict in yes_restrict, no_restrict:
+ # Just check this does not raise
+ assert str(restrict)
+ assert repr(restrict)
+
+
+class AnyMatchTest(TestCase):
+
+ # Most of AnyMatch is tested through test_restriction.
+
+ def test_force(self):
+ restrict = values.AnyMatch(values.AlwaysTrue)
+ assert restrict.force_True(None, None, list(range(2)))
+ assert not restrict.force_False(None, None, list(range(2)))