diff --git a/docs/release-notes.rst b/docs/release-notes.rst index 6f8b3e4..f77569c 100644 --- a/docs/release-notes.rst +++ b/docs/release-notes.rst @@ -8,6 +8,7 @@ Next release - Dropped support for pyyaml - Added new cli argument "--encoding ENCODING" that specifies what encoding to open data and schema files with - Enum error strings now output all possible values for easier debugging +- Implement new type email that uses a relative simple regex to validate email addresses according to RFC 5322 Official Standard 1.7.0 (October 3, 2018) diff --git a/docs/validation-rules.rst b/docs/validation-rules.rst index 2415937..55daf8d 100644 --- a/docs/validation-rules.rst +++ b/docs/validation-rules.rst @@ -54,6 +54,10 @@ The following types are available: - **timestamp** - Validates for basic timestamp formats + - **email** + - Validates data is a valid Email address based on RFC 5322 Official Standard + ^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$ + Example diff --git a/pykwalify/types.py b/pykwalify/types.py index beb33ad..87585fb 100644 --- a/pykwalify/types.py +++ b/pykwalify/types.py @@ -4,6 +4,7 @@ # python stdlib import datetime +import re from pykwalify.compat import basestring, bytes DEFAULT_TYPE = "str" @@ -33,7 +34,8 @@ class text(object): "text": text, "any": object, "enum": str, - "none": None + "none": None, + "email": str, } @@ -144,6 +146,12 @@ def is_date(obj): return isinstance(obj, basestring) or isinstance(obj, datetime.date) +def is_email(obj): + """ + """ + return re.match(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", obj) + + tt = { "str": is_string, "int": is_int, @@ -157,4 +165,5 @@ def is_date(obj): "timestamp": is_timestamp, "scalar": is_scalar, "date": is_date, + "email": is_email, } diff --git a/tests/files/fail/test_type_email.yaml b/tests/files/fail/test_type_email.yaml new file mode 100644 index 0000000..9c8c18f --- /dev/null +++ b/tests/files/fail/test_type_email.yaml @@ -0,0 +1,10 @@ +--- +name: email-1 +desc: basic email type validation. Fails if not conforms with RFC 5322 Official Standard +# +schema: + type: email +data: + "foobar|gmail.com" +errors: + - "Value 'foobar|gmail.com' is not of type 'email'. Path: ''" diff --git a/tests/files/success/test_type_email.yaml b/tests/files/success/test_type_email.yaml new file mode 100644 index 0000000..4dd4bee --- /dev/null +++ b/tests/files/success/test_type_email.yaml @@ -0,0 +1,8 @@ +--- +name: email-1 +desc: basic email type validation. Fails if not conforms with RFC 5322 Official Standard +# +schema: + type: email +data: + "foobar@gmail.com" diff --git a/tests/test_core.py b/tests/test_core.py index bd974df..5f0d184 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -437,6 +437,8 @@ def test_core_files(self): "test_type_text.yaml", # All tests for TYPE: timestamp "test_type_timestamp.yaml", + # All tests for TYPE: email + "test_type_email.yaml", ] _fail_tests = [ @@ -518,6 +520,8 @@ def test_core_files(self): ("test_type_text.yaml", SchemaError), # All tests for TYPE: timestamp ("test_type_timestamp.yaml", SchemaError), + # All tests for TYPE: email + ("test_type_email.yaml", SchemaError), ] # Add override magic to make it easier to test a specific file