def test_invoke(self): cxt = ValidationContext().put(ver1=False, ver2=False, value=0) val = validate_dict(TestNoDependency.V, dict( v1="2", v2="abc", ), cxt).get() assert val.ver1() is True assert val.ver2(ValidationContext().put(value=3)) is False
def test_emptiness(self): r = Requirement(empty=RequirementPolicy.FAIL) f, b = r.validate( "a", ValidationContext().configure(empty_specs=[(str, lambda x: x == "a")])) assert isinstance(f, EmptyFailure) assert f.name == "empty" assert not b f, b = r.validate( "a", ValidationContext().configure(empty_specs=[(str, lambda x: x == "b")])) assert f is None assert b
def test_root(self): c = ValidationContext().put( a1=1, a2="a", ) assert c.a1 == 1 assert c.a2 == "a"
def test_fail(self, share): c = ValidationContext().configure(share_context=share) r = self._validate( dict( v1=dict( p1=dict(q1=1, q2=2, q3=11), p2=dict(q1="1", q2="2", q3=12), p3=3, ), v2=dict(q1="1", q2=2, q3=21), v3=4, ), c) value = r.get() failures = r.failures assert value.v1 is None assert (value.v2.q1, value.v2.q2) == (1, 2) assert {str(p) for p, _ in failures} == {"v1.p2.q1", "v1.p2.q2"} if share: assert c.remainders == dict( v1=dict(p3=3), v3=4, ) assert r.context._contexts == {} else: assert c.remainders == dict(v3=4) assert c["v1"].remainders == dict(p3=3) assert c["v2"].remainders == dict() assert c["v1"]["p1"].remainders == dict() assert c["v1"]["p2"].remainders == dict() assert r.context._contexts != {}
def _validate(self, values, share=False): class V: # don't fail v1: v(str) = "v1" # required v2: +v(str) = "v2" # converter v3: v(int) = 3 # converter without default v4: v(int) # named converter v5: v(("c5", int)) = 5 # Enum v6: v(E) = E.E2 # converter with partial v7: v(p(int, base=2)) = 7 # verifier v8: v(int, gt0) = 8 # verifier without default v9: v(int, gt0) # multiple verifiers v10: v(int, gt0, lt) = 10 # named verifier v11: v(int, ("v13", gt0)) = 11 # verifier with partial v12: v(int, p(gt, th=0)) = 12 return validate_dict( V, values, ValidationContext().configure(share_context=share))
def test_typed(self): c = ValidationContext() c["v1"]["p2"].configure(isinstance_builtin=False, ignore_remainders=False) c["v2"].configure(isinstance_builtin=True) c["v2"]["q1"].configure(isinstance_builtin=False) r = self._validate( dict( v1=dict( p1=dict(q1=1, q2=2, q3=11), p2=dict(q1="1", q2="2", q3=12), p3=3, ), v2=dict(q1="1", q2=2, q3=21), v3=4, ), c) value = r.get() failures = r.failures assert (value.v1.p1.q1, value.v1.p1.q2) == (1, 2) assert (value.v1.p2.q1, value.v1.p2.q2) == (1, 2) assert (value.v1.p2.q1, value.v1.p2.q2) == (1, 2) assert (value.v2.q1, value.v2.q2) == (1, 2) assert c.remainders == dict(v3=4) assert c["v1"].remainders == dict(p3=3) assert c["v2"].remainders == dict() assert c["v1"]["p1"].remainders == dict() assert c["v1"]["p2"].remainders == dict(q3=12) assert r.context._contexts != {}
def test_context(self): def fail(v, cxt:ValidationContext): raise ValidationFailure(name=str(cxt.path)) c = Converter("test", fail, True) v, f = c.convert(["1", "2", "3"], ValidationContext()) assert v is None assert [f[i].name for i in range(3)] == ["[0]", "[1]", "[2]"]
def test_fail_lt_unjointed(self): v = self._validator() cxt = ValidationContext() cxt.configure(join_on_fail=False) r, f, b = v.validate([1, 10, 3], cxt) assert r == [1, None, 3] assert f[1].name == "lt" assert not b
def test_context(self): def fail(v, cxt: ValidationContext): raise ValidationFailure(name=str(cxt.path)) v = Verifier("test", fail, True) f = v.verify([3, 2, 1], ValidationContext()) assert len(f) == 3 assert [f[i].name for i in range(3)] == ["[0]", "[1]", "[2]"]
def test_exception_unjointed(self): c = Converter("test", int, True) cxt = ValidationContext() cxt.config.join_on_fail = False v, f = c.convert(["1", "a", "3"], cxt) assert v == [1, None, 3] assert isinstance(f, CompositeValidationFailure) assert isinstance(f[1], ConversionFailure)
def test_inherit(self): c = ValidationContext().put( a1=1, a2="a", )[0].put(a3=3, ) assert c.a1 == 1 assert c.a2 == "a" assert c.a3 == 3
def test_isinstance_builtin(self): c = Converter("test", int, True) cxt = ValidationContext().configure(isinstance_builtin=True, join_on_fail=False) v, f = c.convert(["1", 2, "3"], cxt) assert v == [None, 2, None] assert isinstance(f, CompositeValidationFailure) assert isinstance(f[0], ConversionFailure) assert f[1] is None assert isinstance(f[2], ConversionFailure)
def test_context(self): def fail(v, cxt:ValidationContext): raise ValidationFailure(name=cxt.name) c = Converter("test", fail, False) cxt = ValidationContext().put( name = "context", ) v, f = c.convert("1", cxt) assert v is None assert f.name == "context"
def test_success(self): cxt = ValidationContext().put(ver1=False, ver2=False, value=0) r = validate_dict(TestNoDependency.V, dict( v1="2", v2="abc", ), cxt) assert bool(r) assert not cxt.ver1 assert cxt.ver2
def test_isinstance_builtin(self): c = Converter("test", int, False) cxt = ValidationContext().configure(isinstance_builtin=True) v, f = c.convert("1", cxt) assert v is None assert isinstance(f, ConversionFailure) assert f.converter is c assert f.name == "test" v, f = c.convert(1, cxt) assert v == 1 assert f is None
def test_overwrite(self): c = ValidationContext().put( a1=1, a2="a", )[0].put( a1=2, a3=3, ) assert c.a1 == 2 assert c.a2 == "a" assert c.a3 == 3
def test_fail(self): cxt = ValidationContext().put(ver1=False, ver2=False, value=2) r = validate_dict(TestNoDependency.V, dict( v1="2", v2="abc", ), cxt) assert not bool(r) assert not cxt.ver1 assert cxt.ver2 assert r.failures['ver1'] is None assert r.failures['ver2'] is not None
def test_isinstance_any(self): class T: def __init__(self, t): self.t = t c = Converter("test", T, False) cxt = ValidationContext().configure(isinstance_any=True) v, f = c.convert("1", cxt) assert v is None assert isinstance(f, ConversionFailure) assert f.converter is c assert f.name == "test" v, f = c.convert(T("1"), cxt) assert v.t == "1" assert f is None
def _validate(self, values, share): class V: v1: v([int]) = [1] v2: +v([int]) = [2] v3: v([("c2", int)]) = [3] v4: v([E]) = [E.E5] v5: v([p(int, base=2)]) = [5] v6: v([int], [gt0]) = [6] v7: v([int], [gt0], [lt]) = [7] v8: v([int], [gt0], longer) = [8] return validate_dict( V, values, ValidationContext().configure(share_context=share))
def test_isinstance_any(self): class T: def __init__(self, t): self.t = t c = Converter("test", T, True) cxt = ValidationContext().configure(isinstance_any=True, join_on_fail=False) v, f = c.convert(["1", T(2), "3"], cxt) assert v[0] is None assert v[1].t == 2 assert v[2] is None assert isinstance(f, CompositeValidationFailure) assert isinstance(f[0], ConversionFailure) assert f[1] is None assert isinstance(f[2], ConversionFailure)
def test_each(self): c = ValidationContext() c0 = c[0] c1 = c[1] c2 = c[2] c0.configure(name="c0") c1.configure(name="c1") c00 = c[0][0] c00.configure(name="c00") c10 = c[1][0] assert c.config.name == "default" assert c0.config.name == "c0" assert c1.config.name == "c1" assert c2.config.name == "default" assert c00.config.name == "c00" assert c10.config.name == "c1"
def _validate(self, context=None, share=False): class C: c1: +v([int]) = [1] c2: +v(int) = 2 class P: p1: +v({C}) = None p2: +v([{C}]) = [] class V: v1: +v({P}) = None v2: +v([{P}]) = [] context = (context or ValidationContext()).configure(share_context=share) return validate_dict( V, dict( v1=dict( p1=dict(c1=["1"], c2="2", c3="c3"), p2=[ dict(c1=["11"], c2="22", c3="c3_1"), dict(c1=["11"], c2="22", c3="c3_2"), ], p3=43, ), v2=[ dict( p1=dict(c1=["1"], c2="2", c3="c23_1"), p2=[ dict(c1=["11"], c2="22", c3="c23_1_1"), dict(c1=["11"], c2="22", c3="c23_1_2"), ], p3=54, ), dict( p1=dict(c1=["1"], c2="2", c3="c23_2"), p2=[ dict(c1=["11"], c2="22", c3="c23_2_1"), dict(c1=["11"], c2="22", c3="c23_2_2"), ], p3=65, ), ], v3=32, ), context)
def test_typed(self): @dhampyr(name="D") class D: v2: v(int) @dhampyr(name="C") class C: v1: v({D}) c = ValidationContext() assert c.config.name == "default" with c.on(C): assert c.config.name == "C" with c.on(D): assert c.config.name == "D" assert c.config.name == "C" assert c.config.name == "default"
def _validate(self, values, context=None, share=False): class C: c1: +v([int], [gt0]) = [1] c2: +v(int, gt0) = 2 class P: p1: +v({C}) = None p2: +v([{C}]) = [] class V: v1: +v({P}) = None v2: +v([{P}]) = [] context = (context or ValidationContext()).configure(share_context=share) return validate_dict(V, values, context)
def test_ignore(self): c = ValidationContext() c["v1"].configure(ignore_remainders=True) c["v2"][0].configure(ignore_remainders=True) r = self._validate(c) assert r.context.remainders == dict(v3=32) assert r.context["v1"].remainders == dict() assert r.context["v1"]["p1"].remainders == dict() assert r.context["v1"]["p2"][0].remainders == dict() assert r.context["v1"]["p2"][1].remainders == dict() assert r.context["v2"][0].remainders == dict() assert r.context["v2"][1].remainders == dict(p3=65) assert r.context["v2"][0]["p1"].remainders == dict() assert r.context["v2"][1]["p1"].remainders == dict(c3="c23_2") assert r.context["v2"][0]["p2"][0].remainders == dict() assert r.context["v2"][0]["p2"][1].remainders == dict() assert r.context["v2"][1]["p2"][0].remainders == dict(c3="c23_2_1") assert r.context["v2"][1]["p2"][1].remainders == dict(c3="c23_2_2") assert r.context._contexts != {}
def test_each_typed(self): @dhampyr(name="D") class D: v2: v(int) @dhampyr(name="C") class C: v1: v({D}) c = ValidationContext() c0 = c[0] with c0.on(C): assert c0.config.name == "C" with c0.on(D): assert c0.config.name == "D" c0.configure(name="c0") with c0.on(C): assert c0.config.name == "c0" c00 = c0[0] with c00.on(C): assert c00.config.name == "c0"
def test_empty_parent_unjointed(self, share): r = self._validate(dict( v1=dict(), v2=[ dict(), dict( p1=dict(c1="12", c2="4"), p2=[dict(c1="34", c2="5")], ), ], ), ValidationContext().configure(join_on_fail=False), share=share) assert not r assert [str(p) for p, f in r.failures] \ == ["v1.p1", "v1.p2", "v2[0].p1", "v2[0].p2"] assert r.get().v1 is None assert r.get().v2[0] is None assert r.get().v2[1].p1.c1 == [1, 2] assert r.get().v2[1].p1.c2 == 4 assert r.get().v2[1].p2[0].c1 == [3, 4] assert r.get().v2[1].p2[0].c2 == 5 assert (not share) or r.context._contexts == {}
def test_root(self): c = ValidationContext() assert str(c.path) == ""
def test_indexes(self): c = ValidationContext()[0][1][2] assert str(c.path) == "[0][1][2]"
def test_root(self): c = ValidationContext() assert c.config.name == "default"