def test_type(): number = blazon.schema({"type": int}) assert number.validate(1) assert not number.validate("1") assert number(1) == 1 assert number("1") == 1 with pytest.raises(ValueError): number("beatrice") class A: def __init__(self, index): self.index = int(index) a_type = blazon.schema({"type": A}) a = A(1) assert a_type.validate(a) assert not a_type.validate(None) assert a_type(a) is a assert a_type(1).index == 1 with pytest.raises(ValueError): a_type("beatrice")
def test_minimum(): s = blazon.schema({"minimum": 0}) assert not s.validate(-10) assert not s.validate(-1) assert s.validate(0) assert s.validate(4) assert s(-10) == 0 assert s(-1) == 0 assert s(0) == 0 assert s(4) == 4 # Exclusive minimum changes our validation assert s.validate(0) s.value["exclusive_minimum"] = True s.compile() assert s(10) == 10 with pytest.raises(blazon.ValidationError): assert s(-10) s.value["exclusive_minimum"] = False s.compile() assert s.validate(0) assert s(-10) == 0 s.value.pop("exclusive_maximum", 0) s.compile() assert s.validate(0) assert s(-10) == 0 # Exclusive minimum validates whatever s = blazon.schema({"exclusive-minimum": True}) assert s.validate(5) assert s.validate(None)
def test_all_of(): s = blazon.schema({ "allOf": [{ "type": str, "max_length": 6 }, { "type": str, "min_length": 3 }] }) assert not s.validate("") assert s.validate("foo") assert s.validate("foobar") assert not s.validate("foobarbar") s = blazon.schema({ "allOf": [{ "type": str, "max_length": 3 }, { "type": int, "maximum": 5 }] }) assert s("666---") == 5
def test_any_of(): s = blazon.schema({ "anyOf": [{ "type": int, "maximum": 4 }, { "type": int, "multiple-of": 4 }] }) assert s.validate(1) assert s.validate(2) assert s.validate(4) assert not s.validate(5) assert s.validate(8) assert not s.validate(10) s = blazon.schema({"anyOf": [{"type": int, "maximum": 4}, {"type": str}]}) assert s.validate("asdf") assert s.validate(4) assert s("asdf") == "asdf" assert s(10) == 4
def test_additional_items(): s = blazon.schema({ "items": [{ "const": 1 }, { "const": 2 }, { "const": 3 }], "additional-items": { "const": 0 } }) assert s.validate([1, 2, 3]) assert s.validate([1, 2, 3, 0, 0]) assert not s.validate([1, 2, 3, 4, 5]) s = blazon.schema({ "items": [{ "const": 1 }, { "const": 2 }, { "const": 3 }], "additional-items": False }) assert s.validate([1, 2, 3]) assert not s.validate([1, 2, 3, 0, 0])
def test_iri(): # Skip this test if we don't have the rfc module. pytest.importorskip("rfc3987") s = blazon.schema({"type": str, "format": "iri"}) assert s.validate("http://tools.ietf.org/html/rfc3986#appendix-A") assert not s.validate("antidisestablishmentarianism") s = blazon.schema({"type": str, "format": "iri-reference"}) assert s.validate("urn:place/sub")
def test_pattern(): s = blazon.schema({"pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"}) assert s.validate("555-1212") assert s.validate("(888)555-1212") assert not s.validate("(888)555-1212 ext. 532") assert not s.validate("(800)FLOWERS") assert not s.validate("None") s = blazon.schema({"pattern": "ob"}) assert s.validate("foobar") assert not s.validate("--")
def test_const(): s = blazon.schema({"const": 5}) assert s.validate(5) assert not s.validate(4) assert s(1) == 5 s = blazon.schema({"const": "jane"}) assert s.validate("jane") assert not s.validate("bob") assert s("bob") == "jane"
def test_multiple_of(): s = blazon.schema({"multiple-of": 2}) assert s.validate(4) assert s.validate(2) assert not s.validate(3) assert not s.validate(1) with pytest.raises(blazon.ValidationError): s(5) s = blazon.schema({"multiple-of": 1.5}) assert s.validate(3) assert not s.validate(4)
def test_items(): # List s = blazon.schema({"items": {"const": 5}}) assert s.validate([5]) assert s.validate([5, 5, 5, 5]) assert not s.validate([1]) assert not s.validate([5, 5, 5, 1]) # Tuple s = blazon.schema({"items": ({"const": 1}, {"const": 2}, {"const": 3})}) assert s.validate([1, 2, 3]) assert s.validate([1, 2, 3, 4, 5]) assert not s.validate([1]) assert not s.validate([1, 2]) assert not s.validate([])
def test_required(): s = blazon.schema({"required": ["a", "b"]}) assert s.validate({"a": 1, "b": 2, "c": 3}) assert s.validate({"a": 1, "b": 2}) assert not s.validate({"a": 1}) assert not s.validate({})
def test_additional_properties(): s = blazon.schema( { "entries": {"name": {"type": str}}, "patternEntries": {"review-(\d+)": {"type": int}}, "additionalEntries": {"type": list}, } ) assert s.validate({"name": "carol", "review-1": 4, "review-2": 3}) assert s.validate({"name": "carol", "review-1": 4, "review-2": 3, "additional": [1, 2, 3]}) assert not s.validate({"name": "carol", "review-1": 4, "review-2": 3, "additional": 4}) s = blazon.schema({"entries": {"name": {"type": str}}, "additionalEntries": False,}) assert not s.validate({"name": "carol", "additional": "yeah"})
def test_max_entries(): s = blazon.schema({"max-entries": 2}) assert s.validate({}) assert s.validate({"a": 1}) assert s.validate({"a": 1, "b": 2}) assert not s.validate({"a": 1, "b": 2, "c": 3})
def test_contains(): s = blazon.schema({"contains": {"const": 1}}) assert s.validate([1, 2, 3]) assert s.validate([1, 1, 1]) assert not s.validate([]) assert not s.validate([2, 3, 4])
def test_hostname(): s = blazon.schema({"type": str, "format": "hostname"}) assert s.validate("www.example.com") assert s.validate("forge.works") assert not s.validate("--") assert not s.validate("/hello/")
def test_property_names(): s = blazon.schema({"entryNames": {"type": str, "min_length": 3},}) assert s.validate({}) assert s.validate({"foo": 1}) assert s.validate({"foo": 1, "foobar": 2}) assert not s.validate({"foo": 1, "foobar": 2, "x": 3}) assert not s.validate({"x": 3})
def test_max_items(): s = blazon.schema({"maxItems": 3}) assert s.validate([]) assert s.validate([1, 2, 3]) assert not s.validate([1, 2, 3, 4, 5]) assert s([1, 2, 3, 4, 5]) == [1, 2, 3]
def test_ip_addresses(): s = blazon.schema({"type": str, "format": "ipv4"}) assert s.validate("127.0.0.1") assert not s.validate("277.0.0.1") assert not s.validate("-") s = blazon.schema({"type": str, "format": "ipv6"}) assert s.validate("2001:db8::") assert s.validate("2001:DB8:0:0:8:800:200C:417A") assert s.validate("FF01:0:0:0:0:0:0:101") assert s.validate("0:0:0:0:0:0:0:0") assert s.validate("0:0:0:0:0:0:0:1") assert s.validate("::") assert not s.validate("-") assert not s.validate("1200::AB00:1234::2552:7777:1313")
def test_uniqueness(): s = blazon.schema({"uniqueItems": True}) assert s.validate([1, 2, 3]) assert s.validate([]) assert not s.validate([2, 2]) assert not s.validate([1, 2, 3, 1]) assert s([1, 2, 3, 1]) == {1, 2, 3}
def test_max_length(): s = blazon.schema({"max-length": 5}) assert s.validate("foo") assert s.validate("foob") assert s.validate("fooba") assert not s.validate("foobar") assert s("foobar") == "fooba"
def test_min_length(): s = blazon.schema({"min-length": 5}) assert s.validate("foobarfoobarfoobar") assert s.validate("foobar") assert not s.validate("foo") assert not s.validate("") with pytest.raises(blazon.ValidationError): assert s("foo")
def test_enum(): s = blazon.schema({"enum": ["bob", "carol", "jane"]}) assert s.validate("bob") assert s.validate("carol") assert s.validate("jane") assert not s.validate("asdfasf") assert not s.validate(None) with pytest.raises(ValidationError): s(None)
class Person(Schematic): __schema__ = blazon.schema({ "entries": { "name": { "type": str }, "age": { "type": int, "minimum": 0, "default": 42 }, }, "required": ["name"], })
def test_pattern_properties(): s = blazon.schema( { "patternEntries": { "name": {"type": str, "min_length": 3}, "review-(\d+)": {"type": int, "minimum": 0, "maximum": 5}, } } ) assert s.validate( {"name": "carol", "review-1": 4, "review-2": 3, "review": 50, "review-extra": -40} ) assert not s.validate({"name": "carol", "review-1": 10})
def test_dependencies(): s = blazon.schema({"dependencies": {"credit_card": ["billing_address"]}}) assert s.validate({}) assert s.validate({"billing_address": "42 Main St"}) assert not s.validate({"credit_card": "4141-414141-414141"}) assert s.validate({"credit_card": "4141-414141-414141", "billing_address": "42 Main St"}) s = blazon.schema( { "dependencies": { "credit_card": { "entries": {"billing_address": {"type": str}}, "required": ["billing_address"], } } } ) assert s.validate({}) assert s.validate({"billing_address": "42 Main St"}) assert not s.validate({"credit_card": "4141-414141-414141"}) assert s.validate({"credit_card": "4141-414141-414141", "billing_address": "42 Main St"}) assert not s.validate({"credit_card": "4141-414141-414141", "billing_address": ["bob"]})
def test_one_of(): s = blazon.schema({ "oneOf": [{ "type": int, "maximum": 4 }, { "type": int, "multiple-of": 4 }] }) assert s.validate(1) assert s.validate(2) assert not s.validate(4) assert not s.validate(5) assert s.validate(8) assert not s.validate(10)
def test_entries(): s = blazon.schema( { "entries": { "name": {"type": str, "min_length": 3}, "age": {"type": int, "minimum": 18, "maximum": 130}, } } ) assert s.validate({"name": "bob", "age": 41}) assert s.validate({"name": "bob", "age": 41, "other": 2}) assert not s.validate({"name": "bob", "age": 400}) assert not s.validate({"name": "?", "age": 14}) # Missing entries are ignored assert s.validate({})
def test_if_then_else(): s = blazon.schema({ "if": { "maximum": 4 }, "then": { "multiple-of": 2 }, "else": { "multiple-of": 3 }, }) assert not s.validate(1) assert s.validate(2) assert not s.validate(3) assert s.validate(4) assert not s.validate(5) assert s.validate(6) assert not s.validate(7) assert not s.validate(8) assert s.validate(9) assert not s.validate(10) assert s.validate(12)
def test_maximum_with_bad_input(): s = blazon.schema({"type": int, "maximum": 4}) assert not s.validate("asdf")
def test_min_items(): s = blazon.schema({"minItems": 3}) assert not s.validate([]) assert s.validate([1, 2, 3]) assert s.validate([1, 2, 3, 4, 5])