730 lines
20 KiB
Python
730 lines
20 KiB
Python
import pytest
|
|
|
|
from toga import validators
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Exact minimum size
|
|
("exact", dict(length=5), None),
|
|
# Exceeds minimum size
|
|
("this is a long string", dict(length=5), None),
|
|
# Allow empty strings
|
|
("", dict(length=5), None),
|
|
# Too short
|
|
(
|
|
"bad!",
|
|
dict(length=5),
|
|
"Input is too short (length should be at least 5)",
|
|
),
|
|
# Too short, different length
|
|
(
|
|
"this is a long string",
|
|
dict(length=25),
|
|
"Input is too short (length should be at least 25)",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"bad",
|
|
dict(length=5, error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(length=5, allow_empty=False),
|
|
"Input is too short (length should be at least 5)",
|
|
),
|
|
],
|
|
)
|
|
def test_min_length(value, kwargs, error):
|
|
validator = validators.MinLength(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Exact max size
|
|
("right size", dict(length=10), None),
|
|
# Less than max size
|
|
("valid", dict(length=10), None),
|
|
# Empty strings are less than any max length
|
|
("", dict(length=10), None),
|
|
# Just exceeds maximum length
|
|
(
|
|
"bad size!!!",
|
|
dict(length=10),
|
|
"Input is too long (length should be at most 10)",
|
|
),
|
|
# Exceeds maximum length
|
|
(
|
|
"this is a long string",
|
|
dict(length=10),
|
|
"Input is too long (length should be at most 10)",
|
|
),
|
|
# Exceeds a different maximum length
|
|
(
|
|
"this is a long string",
|
|
dict(length=5),
|
|
"Input is too long (length should be at most 5)",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"this is a long string",
|
|
dict(length=10, error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
],
|
|
)
|
|
def test_max_length(value, kwargs, error):
|
|
validator = validators.MaxLength(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Exact max size
|
|
("right size", dict(min_length=5, max_length=10), None),
|
|
# Middle size
|
|
("all good", dict(min_length=5, max_length=10), None),
|
|
# Exact min size
|
|
("valid", dict(min_length=5, max_length=10), None),
|
|
# Allow empty strings
|
|
("", dict(min_length=5, max_length=10), None),
|
|
# Just Exceeds maximum length
|
|
(
|
|
"bad size!!!",
|
|
dict(min_length=5, max_length=10),
|
|
"Input should be between 5 and 10 characters",
|
|
),
|
|
# Just less than minimum length
|
|
(
|
|
"bad!",
|
|
dict(min_length=5, max_length=10),
|
|
"Input should be between 5 and 10 characters",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"this is a long string",
|
|
dict(min_length=5, max_length=10, error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(min_length=5, max_length=10, allow_empty=False),
|
|
"Input should be between 5 and 10 characters",
|
|
),
|
|
],
|
|
)
|
|
def test_length_between(value, kwargs, error):
|
|
validator = validators.LengthBetween(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
def test_invalid_range():
|
|
"""Minimum value must be less than maximum value."""
|
|
with pytest.raises(
|
|
ValueError,
|
|
match=r"Minimum length cannot be less than maximum length",
|
|
):
|
|
validators.LengthBetween(min_length=10, max_length=5)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Exact match
|
|
("hello", dict(substring="hello"), None),
|
|
# Starts with match
|
|
("hello world", dict(substring="hello"), None),
|
|
# Allow empty strings
|
|
("", dict(substring="hello"), None),
|
|
# Doesn't start with match
|
|
(
|
|
"bad string",
|
|
dict(substring="hello"),
|
|
"Input should start with 'hello'",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"bad string",
|
|
dict(substring="hello", error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(substring="hello", allow_empty=False),
|
|
"Input should start with 'hello'",
|
|
),
|
|
],
|
|
)
|
|
def test_startswith(value, kwargs, error):
|
|
validator = validators.StartsWith(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Exact match
|
|
("goodbye", dict(substring="goodbye"), None),
|
|
# Ends with match
|
|
("the final goodbye", dict(substring="goodbye"), None),
|
|
# Allow empty strings
|
|
("", dict(substring="goodbye"), None),
|
|
# Doesn't end with match
|
|
(
|
|
"bad string",
|
|
dict(substring="goodbye"),
|
|
"Input should end with 'goodbye'",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"bad string",
|
|
dict(substring="goodbye", error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(substring="goodbye", allow_empty=False),
|
|
"Input should end with 'goodbye'",
|
|
),
|
|
],
|
|
)
|
|
def test_endswith(value, kwargs, error):
|
|
validator = validators.EndsWith(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Exact single match
|
|
("hello", dict(substring="hello"), None),
|
|
# Starts with match
|
|
("hello is what you should say", dict(substring="hello"), None),
|
|
# Ends with match
|
|
("You should say hello", dict(substring="hello"), None),
|
|
# Contains substring
|
|
("Say hello, you fool", dict(substring="hello"), None),
|
|
# Contains multiple examples of substring
|
|
("Say hello, and hello again", dict(substring="hello"), None),
|
|
# Contains exact match of multiple substrings
|
|
("Say hello, and hello again", dict(substring="hello", count=2), None),
|
|
# Count of 0 validates non-existence
|
|
("Say hello, and hello again", dict(substring="bad", count=0), None),
|
|
# Allow empty strings
|
|
("", dict(substring="hello"), None),
|
|
# Doesn't contain match
|
|
(
|
|
"bad string",
|
|
dict(substring="hello"),
|
|
"Input should contain 'hello'",
|
|
),
|
|
# Contain match with a count of 0
|
|
(
|
|
"hello world",
|
|
dict(substring="hello", count=0),
|
|
"Input should not contain 'hello'",
|
|
),
|
|
# Contain match, but not the right count
|
|
(
|
|
"hello world",
|
|
dict(substring="hello", count=2),
|
|
"Input should contain 'hello' exactly 2 times",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"bad string",
|
|
dict(substring="hello", error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(substring="hello", allow_empty=False),
|
|
"Input should contain 'hello'",
|
|
),
|
|
],
|
|
)
|
|
def test_contains(value, kwargs, error):
|
|
validator = validators.Contains(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# No match
|
|
("nothing to see", dict(substring="hello"), None),
|
|
# Allow empty strings (an empty string can't contain a substring)
|
|
("", dict(substring="hello"), None),
|
|
# Starts with match
|
|
(
|
|
"hello is what you should say",
|
|
dict(substring="hello"),
|
|
"Input should not contain 'hello'",
|
|
),
|
|
# Ends with match
|
|
(
|
|
"You should say hello",
|
|
dict(substring="hello"),
|
|
"Input should not contain 'hello'",
|
|
),
|
|
# Contains substring
|
|
(
|
|
"Say hello, you fool",
|
|
dict(substring="hello"),
|
|
"Input should not contain 'hello'",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"You should say hello",
|
|
dict(substring="hello", error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
],
|
|
)
|
|
def test_not_contains(value, kwargs, error):
|
|
validator = validators.NotContains(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
# Test regex matches 1 upper case, 2 lower case, then 1 upper case.
|
|
TEST_REGEX = r"[A-Z]{1}[a-z]{2}[A-Z]{1}"
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Exact match
|
|
("GooD", dict(regex_string=TEST_REGEX), None),
|
|
# Match at start
|
|
("GooD is what this is", dict(regex_string=TEST_REGEX), None),
|
|
# Match at end
|
|
("This is also GooD", dict(regex_string=TEST_REGEX), None),
|
|
# Exact match in the middle of the string
|
|
("it's GooD if it's in the middle", dict(regex_string=TEST_REGEX), None),
|
|
# Allow empty strings
|
|
("", dict(regex_string=TEST_REGEX), None),
|
|
# Doesn't match
|
|
(
|
|
"no match here",
|
|
dict(regex_string=TEST_REGEX),
|
|
"Input should match regex: '[A-Z]{1}[a-z]{2}[A-Z]{1}'",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"no match here",
|
|
dict(regex_string=TEST_REGEX, error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(regex_string=TEST_REGEX, allow_empty=False),
|
|
"Input should match regex: '[A-Z]{1}[a-z]{2}[A-Z]{1}'",
|
|
),
|
|
],
|
|
)
|
|
def test_regex(value, kwargs, error):
|
|
validator = validators.MatchRegex(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Only uppercase
|
|
("GOOD!1", dict(), None),
|
|
# Some uppercase
|
|
("Good!1", dict(), None),
|
|
# Some uppercase
|
|
("GooD!1", dict(count=2), None),
|
|
# Count of 0
|
|
("good!1", dict(count=0), None),
|
|
# Allow empty strings
|
|
("", dict(), None),
|
|
# Doesn't match
|
|
(
|
|
"no match here",
|
|
dict(),
|
|
"Input should contain at least one upper case character",
|
|
),
|
|
# Bad count
|
|
(
|
|
"Good!1",
|
|
dict(count=2),
|
|
"Input should contain exactly 2 upper case characters",
|
|
),
|
|
# Explicit count of 0
|
|
(
|
|
"Bad Text!1",
|
|
dict(count=0),
|
|
"Input should not contain upper case characters",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"no match here",
|
|
dict(error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(allow_empty=False),
|
|
"Input should contain at least one upper case character",
|
|
),
|
|
],
|
|
)
|
|
def test_contains_uppercase(value, kwargs, error):
|
|
validator = validators.ContainsUppercase(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Only lower case
|
|
("good!1", dict(), None),
|
|
# Some lower case
|
|
("Good!1", dict(), None),
|
|
# Some lower case, exact count
|
|
("GooD!1", dict(count=2), None),
|
|
# Count of 0
|
|
("GOOD!1", dict(count=0), None),
|
|
# Allow empty strings
|
|
("", dict(), None),
|
|
# Doesn't match
|
|
(
|
|
"NO MATCH HERE!",
|
|
dict(),
|
|
"Input should contain at least one lower case character",
|
|
),
|
|
# Bad count
|
|
(
|
|
"Good!1",
|
|
dict(count=2),
|
|
"Input should contain exactly 2 lower case characters",
|
|
),
|
|
# Explicit count of 0
|
|
(
|
|
"Bad Text!1",
|
|
dict(count=0),
|
|
"Input should not contain lower case characters",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"NO MATCH HERE!",
|
|
dict(error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(allow_empty=False),
|
|
"Input should contain at least one lower case character",
|
|
),
|
|
],
|
|
)
|
|
def test_contains_lowercase(value, kwargs, error):
|
|
validator = validators.ContainsLowercase(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Only digits
|
|
("1234", dict(), None),
|
|
# Some digits
|
|
("Good!12345", dict(), None),
|
|
# Some digits, exact count
|
|
("GooD12!", dict(count=2), None),
|
|
# Count of 0
|
|
("good!", dict(count=0), None),
|
|
# Allow empty strings
|
|
("", dict(), None),
|
|
# Doesn't match
|
|
(
|
|
"no match here",
|
|
dict(),
|
|
"Input should contain at least one digit",
|
|
),
|
|
# Bad count
|
|
(
|
|
"Good!1",
|
|
dict(count=2),
|
|
"Input should contain exactly 2 digits",
|
|
),
|
|
# Explicit count of 0
|
|
(
|
|
"Bad Text!1",
|
|
dict(count=0),
|
|
"Input should not contain digits",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"no match here",
|
|
dict(error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(allow_empty=False),
|
|
"Input should contain at least one digit",
|
|
),
|
|
],
|
|
)
|
|
def test_contains_digit(value, kwargs, error):
|
|
validator = validators.ContainsDigit(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Only special
|
|
("!@*&#^(*&!^(&@))", dict(), None),
|
|
# Some special
|
|
("Good!1", dict(), None),
|
|
# Some special, exact count
|
|
("GooD@!", dict(count=2), None),
|
|
# Count of 0
|
|
("good1", dict(count=0), None),
|
|
# Allow empty strings
|
|
("", dict(), None),
|
|
# Doesn't match
|
|
(
|
|
"no match here",
|
|
dict(),
|
|
"Input should contain at least one special character",
|
|
),
|
|
# Bad count
|
|
(
|
|
"Good!1",
|
|
dict(count=2),
|
|
"Input should contain exactly 2 special characters",
|
|
),
|
|
# Explicit count of 0
|
|
(
|
|
"Bad Text!1",
|
|
dict(count=0),
|
|
"Input should not contain special characters",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"no match here",
|
|
dict(error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(allow_empty=False),
|
|
"Input should contain at least one special character",
|
|
),
|
|
],
|
|
)
|
|
def test_contains_special(value, kwargs, error):
|
|
validator = validators.ContainsSpecial(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Zero
|
|
("0", dict(), None),
|
|
# positive integer
|
|
("123", dict(), None),
|
|
# Negative integer
|
|
("-123", dict(), None),
|
|
# Extra space
|
|
(" 123 ", dict(), None),
|
|
# leading zeros
|
|
("01234", dict(), None),
|
|
# Allow empty strings
|
|
("", dict(), None),
|
|
# Doesn't match
|
|
(
|
|
"no match here",
|
|
dict(),
|
|
"Input should be an integer",
|
|
),
|
|
# Contains an integer, but not a pure integer
|
|
(
|
|
"no 123",
|
|
dict(),
|
|
"Input should be an integer",
|
|
),
|
|
# Float
|
|
(
|
|
"1.234",
|
|
dict(),
|
|
"Input should be an integer",
|
|
),
|
|
# Hex
|
|
(
|
|
"0x123",
|
|
dict(),
|
|
"Input should be an integer",
|
|
),
|
|
# Octal
|
|
(
|
|
"0o123",
|
|
dict(),
|
|
"Input should be an integer",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"no match here",
|
|
dict(error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(allow_empty=False),
|
|
"Input should be an integer",
|
|
),
|
|
],
|
|
)
|
|
def test_integer(value, kwargs, error):
|
|
validator = validators.Integer(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Zero
|
|
("0", dict(), None),
|
|
# positive integer
|
|
("123", dict(), None),
|
|
# Negative integer
|
|
("-123", dict(), None),
|
|
# Extra space
|
|
(" 123 ", dict(), None),
|
|
# leading zeros
|
|
("01234", dict(), None),
|
|
# Float
|
|
("12.34", dict(), None),
|
|
# Negative Float
|
|
("-12.34", dict(), None),
|
|
# Float, no leading 0
|
|
(".1234", dict(), None),
|
|
# Negative Float, no leading 0
|
|
("-.1234", dict(), None),
|
|
# Exponential
|
|
("1.23e+4", dict(), None),
|
|
# Negative Exponential
|
|
("-1.23e-4", dict(), None),
|
|
# Exponential (capitalized)
|
|
("1.23E+4", dict(), None),
|
|
# Negative (capitalized)
|
|
("-1.23E-4", dict(), None),
|
|
# Allow empty strings
|
|
("", dict(), None),
|
|
# Doesn't match
|
|
(
|
|
"no match here",
|
|
dict(),
|
|
"Input should be a number",
|
|
),
|
|
# Contains a number, but not a pure number
|
|
(
|
|
"no 1.23",
|
|
dict(),
|
|
"Input should be a number",
|
|
),
|
|
# Just a decimal point isn't a number
|
|
(
|
|
".",
|
|
dict(),
|
|
"Input should be a number",
|
|
),
|
|
# Just an exponent isn't a number
|
|
(
|
|
"e+9",
|
|
dict(),
|
|
"Input should be a number",
|
|
),
|
|
# Custom error message
|
|
(
|
|
"no match here",
|
|
dict(error_message="Badness"),
|
|
"Badness",
|
|
),
|
|
# Don't allow empty strings
|
|
(
|
|
"",
|
|
dict(allow_empty=False),
|
|
"Input should be a number",
|
|
),
|
|
],
|
|
)
|
|
def test_number(value, kwargs, error):
|
|
validator = validators.Number(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value, kwargs, error",
|
|
[
|
|
# Valid email addresses
|
|
("tiberius@beeware.org", dict(), None),
|
|
("tiberius.yak@beeware.org", dict(), None),
|
|
("tiberius+yak@beeware.org", dict(), None),
|
|
("tiberius@beeware.ab.cd", dict(), None),
|
|
("tiberius@localhost", dict(), None),
|
|
("tiberius@beeware", dict(), None),
|
|
("2iberius@beeware.org", dict(), None),
|
|
# Allow empty strings
|
|
("", dict(), None),
|
|
# Invalid email addresses
|
|
("tiberius.beeware.org", dict(), "Input should be a valid email address"),
|
|
("tiberius@me@beeware.org", dict(), "Input should be a valid email address"),
|
|
("tiberius@beeware.", dict(), "Input should be a valid email address"),
|
|
# Custom error message
|
|
("not an email", dict(error_message="badness"), "badness"),
|
|
# Disallow empty strings
|
|
("", dict(allow_empty=False), "Input should be a valid email address"),
|
|
],
|
|
)
|
|
def test_email(value, kwargs, error):
|
|
validator = validators.Email(**kwargs)
|
|
|
|
assert validator(value) == error
|
|
|
|
|
|
# @pytest.mark.parametrize(
|
|
# "value",
|
|
# [
|
|
# ],
|
|
# )
|
|
# def test_invalid_email(value):
|
|
# validator = validators.Email()
|
|
|
|
# assert validator(value) == "Input should be a valid email address"
|