def test_failure(self): class C: v1: v(int, key="value-1") r = validate_dict(C, {"value-1": "a"}) assert r.failures['v1'] is not None assert [(str(p), f.name) for p, f in r.failures] == [("v1", "int")]
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_default(self): try: with dhampyr() as cfg: cfg.skip_null = False cfg.join_on_fail = False cfg.isinstance_builtin = True config = default_config() assert config.skip_null is False assert config.join_on_fail is False assert config.isinstance_builtin is True class V: v1: v(lambda x: 0 if x is None else 1) v2: v([int]) r = validate_dict(V, dict(v1=None, v2=["a", 1, "2"])) assert not r assert r.failures['v1'] is None assert r.get().v1 == 0 assert r.failures['v2'] is not None assert r.get().v2 == [None, 1, None] finally: config = default_config() config.skip_null = True config.skip_empty = True config.allow_null = False config.allow_empty = False config.isinstance_builtin = False config.isinstance_any = False config.join_on_fail = True
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_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_decorator(self): @dhampyr(skip_null=False, join_on_fail=False, isinstance_builtin=True) class V: v1: v(lambda x: 0 if x is None else 1) v2: v([int]) r = validate_dict(V, dict(v1=None, v2=["a", 1, "2"])) assert not r assert r.failures['v1'] is None assert r.get().v1 == 0 assert r.failures['v2'] is not None assert r.get().v2 == [None, 1, None]
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 _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 _validate(self, values, context=None): @dhampyr(ignore_remainders=True) class Q: q1: +v(int) q2: +v(int) @dhampyr(isinstance_builtin=True) class P: p1: +v({Q}) = None p2: +v({Q}) = None class V: v1: +v({P}) = None v2: +v({Q}) = None return validate_dict(V, values, context=context)
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 _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_key_filter(self): class U: u1: +v(int) @dhampyr(key_filter=lambda k: f"{k}1") class V: v1: +v(int) v2: +v(str) v3: +v({U}) r = validate_dict( V, dict(v11=1, v21=2, v1=3, v2=4, v31=dict(u11=5, u1=6))) assert r d = r.get() assert d.v1 == 1 assert d.v2 == "2" assert d.v3.u1 == 5 assert r.context.remainders == dict(v1=3, v2=4) assert r.context["v3"].remainders == dict(u1=6)
def test_all_method_failed(self): r = validate_dict(TestDependency.V, dict(v1=0, v2=0, v3=0)) assert not bool(r) assert {str(p) for p, _ in r.failures} == {"ver1", "ver2", "ver3", "ver4"}
def test_all_failed(self): r = validate_dict(TestDependency.V, dict(v1="a", v2="a", v3="a")) assert not bool(r) assert {str(p) for p, _ in r.failures} == {"v1", "v2", "v3"}
def test_no_failure(self): r = validate_dict(TestDependency.V, dict(v1=1, v2=1, v3=1)) assert bool(r)
def test_success(self): class C: v1: v(int, key="value-1") r = validate_dict(C, {"value-1": "3"}) assert r.get().v1 == 3
def test_multiple_positive(self): r = validate_dict(TestDependency.V, dict(v1=0, v2=0, v3="a")) assert not bool(r) assert {str(p) for p, _ in r.failures} == {"v3", "ver2", "ver3"}
def test_negative(self): r = validate_dict(TestDependency.V, dict(v1=0, v2="a", v3="a")) assert not bool(r) assert {str(p) for p, _ in r.failures} == {"v2", "v3", "ver2"}
def test_malformed(self): class C: v1: v(int) r = validate_dict(C, []) assert [(str(p), f.name) for p, f in r.failures] == [("", "malformed")]