Skip to content
Browse files

Completed internal documentation. Next are unit tests and human-frien…

…dly documents.
  • Loading branch information...
1 parent 33afe5a commit 465f077cb28342f8613d363238290a3da9668271 @wilhelm-murdoch committed Apr 3, 2012
Showing with 320 additions and 223 deletions.
  1. 0 tests/{validator.py → .gitkeep}
  2. +102 −103 validator/core.py
  3. +218 −120 validator/rules.py
View
0 tests/validator.py → tests/.gitkeep
File renamed without changes.
View
205 validator/core.py
@@ -6,150 +6,149 @@
"""
class Rule(object):
- """ Base abstract class representing a "rule". All defined rules must be derived from this class. """
+ """ Base abstract class representing a "rule". All defined rules must be derived from this class. """
- error = None
- """ User-defined error message for a failed rule. """
+ error = None
+ """ User-defined error message for a failed rule. """
- def __init__(self, error = None, *args, **kwargs):
- """ Constructor that instantiates a class instance and properties.
+ def __init__(self, error = None, *args, **kwargs):
+ """ Constructor that instantiates a class instance and properties.
- Keyword arguments:
- error str -- A user-defined error messaged for a failed rule. (optional)
- """
+ Keyword arguments:
+ error str -- A user-defined error messaged for a failed rule. (optional)
+ """
- super(Rule, self).__init__()
- self.error = error
+ super(Rule, self).__init__()
+ self.error = error
- def run(self, *args, **kwargs):
- """ Invoked once a defined rule is ready to be validated. """
+ def run(self, *args, **kwargs):
+ """ Invoked once a defined rule is ready to be validated. """
- raise NotImplementedError, 'This method cannot be accessed directly'
+ raise NotImplementedError, 'This method cannot be accessed directly'
class Field(object):
- """ Class representing a "field". """
+ """ Class representing a "field". """
- rules = []
- """ List containing instances of class Rule associated with this field. """
+ rules = []
+ """ List containing instances of class Rule associated with this field. """
- title = ''
- """ The title of this field. """
+ title = ''
+ """ The title of this field. """
- value = ''
- """ The value associated with this field. """
+ value = ''
+ """ The value associated with this field. """
- def __init__(self, title, value):
- """ Constructor that instantiates a class instance and properties.
+ def __init__(self, title, value):
+ """ Constructor that instantiates a class instance and properties.
- Keyword arguments:
- title str -- The title of this field.
- value str -- The value associated with this field.
- """
+ Keyword arguments:
+ title str -- The title of this field.
+ value str -- The value associated with this field.
+ """
- super(Field, self).__init__()
- self.rules = []
- self.title = title
- self.value = value
+ super(Field, self).__init__()
+ self.rules = []
+ self.title = title
+ self.value = value
- def append(self, rule):
- """ Attaches an instance of class Rule to the current instance of this Field
+ def append(self, rule):
+ """ Attaches an instance of class Rule to the current instance of this Field
- Keyword arguments:
- rule object -- Instance of class Rule to apply to this field.
- """
+ Keyword arguments:
+ rule object -- Instance of class Rule to apply to this field.
+ """
- if isinstance(rule, list):
- for r in rule:
- if not isinstance(r, Rule):
- raise TypeError, 'parameter :rule must be list of class Rule instances'
- self.rules.append(r)
- return self
- elif not isinstance(rule, Rule):
- raise TypeError, 'parameter :rule must be instance of class Rule'
- self.rules.append(rule)
- return self
+ if isinstance(rule, list):
+ for r in rule:
+ if not isinstance(r, Rule):
+ raise TypeError, 'parameter :rule must be list of class Rule instances'
+ self.rules.append(r)
+ return self
+ elif not isinstance(rule, Rule):
+ raise TypeError, 'parameter :rule must be instance of class Rule'
+ self.rules.append(rule)
+ return self
- def run(self, continue_on_error = True):
- """ Iterates through all associated rules, executes them and collects the results. """
- errors = []
- for rule in self.rules:
- if not rule.run(self.value):
- errors.append(rule.error)
- return False if errors else True, errors
+ def run(self):
+ """ Iterates through all associated rules, executes them and collects the results. """
+ errors = []
+ for rule in self.rules:
+ if not rule.run(self.value):
+ errors.append(rule.error)
+ return False if errors else True, errors
class Validator(object):
- """ Responsible for applying rules against the specified fields. """
+ """ Responsible for applying rules against the specified fields. """
- fields = []
- """ List containing instances of class Field associated with this validator. """
+ fields = []
+ """ List containing instances of class Field associated with this validator. """
- collated_results = []
- """ List containing validation results of each field and associated rule. """
+ collated_results = []
+ """ List containing validation results of each field and associated rule. """
- def __init__(self):
- """ Constructor that instantiates a class instance and properties. """
+ def __init__(self):
+ """ Constructor that instantiates a class instance and properties. """
- super(Validator, self).__init__()
- self.fields = []
- self.collated_results = []
+ super(Validator, self).__init__()
+ self.fields = []
+ self.collated_results = []
- def append(self, field):
- """ Attaches an instance of class Field to the current instance of this Validator
+ def append(self, field):
+ """ Attaches an instance of class Field to the current instance of this Validator
- Keyword arguments:
- field object -- Instance of class Field to apply to this Validator.
- """
+ Keyword arguments:
+ field object -- Instance of class Field to apply to this Validator.
+ """
- if isinstance(field, list):
- for f in field:
- if not isinstance(f, Field):
- raise TypeError, 'parameter :field must be list of class Field instances'
- self.fields.append(f)
- return self
- if not isinstance(field, Field):
- raise TypeError, 'parameter :field must be instance of class Field'
- self.fields.append(field)
- return self
+ if isinstance(field, list):
+ for f in field:
+ if not isinstance(f, Field):
+ raise TypeError, 'parameter :field must be list of class Field instances'
+ self.fields.append(f)
+ return self
+ if not isinstance(field, Field):
+ raise TypeError, 'parameter :field must be instance of class Field'
+ self.fields.append(field)
+ return self
- def results(self):
- """ Returns the collated results for the current Validator instance. """
+ def results(self):
+ """ Returns the collated results for the current Validator instance. """
- return self.collated_results
+ return self.collated_results
- def run(self, return_collated_results = False, continue_on_error = True):
- """ Iterates through all associated Fields and applies all attached Rules. Depending on 'return_collated_results',
- this method will either return True (all rules successful), False (all, or some, rules failed) or a dictionary list
- containing the collated results of all Field Rules.
+ def run(self, return_collated_results = False):
+ """ Iterates through all associated Fields and applies all attached Rules. Depending on 'return_collated_results',
+ this method will either return True (all rules successful), False (all, or some, rules failed) or a dictionary list
+ containing the collated results of all Field Rules.
- Keyword arguments:
- return_collated_results bool -- Returns dictionary list of Field Rule collated results.
- continue_on_error bool -- If set to False, this method will break out upon encountering the first error.
- """
+ Keyword arguments:
+ return_collated_results bool -- Returns dictionary list of Field Rule collated results instead of True or False.
+ """
- passed = True
- for field in self.fields:
- result, errors = field.run()
+ passed = True
+ for field in self.fields:
+ result, errors = field.run()
- results = {
- 'field': field.title,
- 'value': field.value,
- 'passed': result
- }
+ results = {
+ 'field': field.title,
+ 'value': field.value,
+ 'passed': result
+ }
- if errors:
- passed = False
- results['errors'] = errors
+ if errors:
+ passed = False
+ results['errors'] = errors
- self.collated_results.append(results)
+ self.collated_results.append(results)
- if return_collated_results:
- return self.collated_results
- return passed
+ if return_collated_results:
+ return self.collated_results
+ return passed
View
338 validator/rules.py
@@ -1,183 +1,281 @@
+#!/usr/bin/env python
+
from validator.core import Rule
import re
+""" Core Rules Module
+
+Contains a comprehensive list of built-in validator rules.
+"""
+
class Matches(Rule):
- """ Simple rule used to determine whether one value matches another. Commonly used
- for password confirmation. """
+ """ Simple rule used to determine whether one value matches another. Commonly used
+ for password confirmation. """
- match = ''
- """ The value to compare against the associated field's value """
+ match = ''
+ """ The value to compare against the associated field's value """
- def __init__(self, match, error = None):
- """ Constructor that instantiates a class instance and properties.
+ def __init__(self, match, error = None):
+ """ Constructor that instantiates a class instance and properties.
- Keyword arguments:
- match str -- The value to compare against the associated field's value.
- error str -- A user-defined error messaged for a failed rule. (optional)
- """
- super(Matches, self).__init__(error)
- self.match = match
+ Keyword arguments:
+ match str -- The value to compare against the associated field's value.
+ error str -- A user-defined error messaged for a failed rule. (optional)
+ """
+ super(Matches, self).__init__(error)
+ self.match = match
- def run(self, field_value):
- """ Invoked once a defined rule is ready to be validated.
+ def run(self, field_value):
+ """ Invoked once a defined rule is ready to be validated.
- Keyword arguments:
- field_value str -- the value of the associated field to compare.
- """
+ Keyword arguments:
+ field_value str -- the value of the associated field to compare.
+ """
- if self.match != field_value:
- if not self.error:
- self.error = "Values `%s` and `%s` do not match." % (field_value, self.match)
- return False
- return True
+ if self.match != field_value:
+ if not self.error:
+ self.error = "Values `%s` and `%s` do not match." % (field_value, self.match)
+ return False
+ return True
class Regex(Rule):
- """ Applies a regular expression to a given field value. """
+ """ Applies a regular expression to a given field value. """
- expression = ''
- """ The regular expression to apply. """
+ expression = ''
+ """ The regular expression to apply. """
- def __init__(self, expression, error = None):
- """ Constructor that instantiates a class instance and properties.
+ def __init__(self, expression, error = None):
+ """ Constructor that instantiates a class instance and properties.
- Keyword arguments:
- expression str -- The regular expression to apply to the given field.
- error str -- A user-defined error messaged for a failed rule. (optional)
- """
- super(Regex, self).__init__(error)
- self.expression = expression
+ Keyword arguments:
+ expression str -- The regular expression to apply to the given field.
+ error str -- A user-defined error messaged for a failed rule. (optional)
+ """
+ super(Regex, self).__init__(error)
+ self.expression = expression
- def run(self, field_value):
- """ Invoked once a defined rule is ready to be validated.
+ def run(self, field_value):
+ """ Invoked once a defined rule is ready to be validated.
- Keyword arguments:
- field_value str -- the value of the associated field to compare
- """
+ Keyword arguments:
+ field_value str -- the value of the associated field to compare
+ """
- if not self.expression:
- raise ValueError, 'This rule requires a regular expression.'
+ if not self.expression:
+ raise ValueError, 'This rule requires a regular expression.'
- try:
- regex = re.compile(self.expression)
+ try:
+ regex = re.compile(self.expression)
- if not regex.match(field_value):
- if not self.error:
- self.error = "Expression `%s` failed when applied to `%s`" % (self.expression, field_value)
- return False
- except Exception, e:
- raise ValueError, "Expression `%s` failed with the following error: %s" % (self.expression, e)
- return True
+ if not regex.match(field_value):
+ if not self.error:
+ self.error = "Expression `%s` failed when applied to `%s`" % (self.expression, field_value)
+ return False
+ except Exception, e:
+ raise ValueError, "Expression `%s` failed with the following error: %s" % (self.expression, e)
+ return True
class IsEmail(Regex):
- def __init__(self, error = None):
- super(IsEmail, self).__init__(r'^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$', error)
- if not error:
- self.error = 'This is not a valid email address.'
+ """ Regex convenience derivative class used to determine if given field value is a
+ valid email address. """
+
+ def __init__(self, error = None):
+ super(IsEmail, self).__init__(r'^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$', error)
+ if not error:
+ self.error = 'This is not a valid email address.'
class IsNumeric(Regex):
- def __init__(self, error = None):
- super(IsNumeric, self).__init__(r'^[0-9]+$', error)
- if not error:
- self.error = 'This is not a number.'
+ """ Regex convenience derivative class used to determine if given field value is numeric-only. """
+
+ def __init__(self, error = None):
+ super(IsNumeric, self).__init__(r'^[0-9]+$', error)
+ if not error:
+ self.error = 'This is not a number.'
class IsAlpha(Regex):
- def __init__(self, error = None):
- super(IsAlpha, self).__init__(r'^[a-zA-Z]+$', error)
- if not error:
- self.error = 'This is not an alpha-only string.'
+ """ Regex convenience derivative class used to determine if given field value is alpha-only. """
+
+ def __init__(self, error = None):
+ super(IsAlpha, self).__init__(r'^[a-zA-Z]+$', error)
+ if not error:
+ self.error = 'This is not an alpha-only string.'
class IsAlphaNumeric(Regex):
- def __init__(self, error = None):
- super(IsAlphaNumeric, self).__init__(r'^[a-zA-Z0-9]+$', error)
- if not error:
- self.error = 'This is not an alpha-numeric string.'
+ """ Regex convenience derivative class used to determine if given field value is alpha-numeric. """
+
+ def __init__(self, error = None):
+ super(IsAlphaNumeric, self).__init__(r'^[a-zA-Z0-9]+$', error)
+ if not error:
+ self.error = 'This is not an alpha-numeric string.'
+
class IsRequired(Regex):
- def __init__(self, error = None):
- super(IsRequired, self).__init__(r'^.{1,}$', error)
- if not error:
- self.error = 'This field requires a value.'
+ """ Regex convenience derivative class used to determine if given field is empty. """
+
+ def __init__(self, error = None):
+ super(IsRequired, self).__init__(r'^.{1,}$', error)
+ if not error:
+ self.error = 'This field requires a value.'
+
class IsLength(Rule):
- length = None
- strip = False
- def __init__(self, length, strip = False, error = None):
- super(IsLength, self).__init__(error)
- self.length = int(length)
- self.strip = bool(strip)
+ """ Used to determine whether the given associated field value's character length equals
+ the given maximum amount. """
- def run(self, field_value):
- if len((field_value.strip() if self.strip else field_value)) != self.length:
- if not self.error:
- self.error = "String `%s` length does not equal `%d`" % (field_value, self.length)
- return False
- return True
+ length = None
+ """ Absolute maximum character length. """
+
+ strip = False
+ """ Determines whether to strip whitespace from either side of the given field value. """
+
+ def __init__(self, length, strip = False, error = None):
+ """ Constructor that instantiates a class instance and properties.
+
+ Keyword arguments:
+ length int -- Absolute maximum character length.
+ strip bool -- Used to strip whitespace from the given field value. (optional)
+ error str -- A user-defined error messaged for a failed rule. (optional)
+ """
+
+ super(IsLength, self).__init__(error)
+ self.length = int(length)
+ self.strip = bool(strip)
+
+ def run(self, field_value):
+ """ Determines if field_value character length equal self.length.
+
+ Keyword arguments:
+ field_value str -- the value of the associated field to compare
+ """
+
+ if len((field_value.strip() if self.strip else field_value)) != self.length:
+ if not self.error:
+ self.error = "String `%s` length does not equal `%d`" % (field_value, self.length)
+ return False
+ return True
class IsLengthBetween(Rule):
- min = 0
- max = 0
- strip = False
+ """ Used to determine whether the given associated field value's character length is
+ within the given range. """
+
+ min = 0
+ """ Absolute minimum character length. """
+
+ max = 0
+ """ Absolute maximum character length. """
- def __init__(self, min, max, strip = False, error = None):
- super(IsLengthBetween, self).__init__(error)
- self.min = int(min)
- self.max = int(max)
- self.strip = bool(strip)
+ strip = False
+ """ Determines whether to strip whitespace from either side of the given field value. """
+
+ def __init__(self, min, max, strip = False, error = None):
+ """ Constructor that instantiates a class instance and properties.
+
+ Keyword arguments:
+ min int -- Absolute minimum character length.
+ max int -- Absolute maximum character length.
+ strip bool -- Used to strip whitespace from the given field value. (optional)
+ error str -- A user-defined error messaged for a failed rule. (optional)
+ """
+
+ super(IsLengthBetween, self).__init__(error)
+ self.min = int(min)
+ self.max = int(max)
+ self.strip = bool(strip)
+
+ def run(self, field_value):
+ """ Determines if field_value character length is between self.min and self.max.
+
+ Keyword arguments:
+ field_value str -- the value of the associated field to compare
+ """
+
+ if self.min <= len((field_value.strip() if self.strip else field_value)) <= self.max:
+ return True
+ if not self.error:
+ self.error = "String `%s` length is not within `%d` and `%d`" % (field_value, self.min, self.max)
+ return False
- def run(self, field_value):
- if self.min <= len((field_value.strip() if self.strip else field_value)) <= self.max:
- return True
- if not self.error:
- self.error = "String `%s` length is not within `%d` and `%d`" % (field_value, self.min, self.max)
- return False
class IsInList(Rule):
- list = []
- strip = False
- def __init__(self, list, strip = False, error = None):
- super(IsInList, self).__init__(error)
- self.list = list
- self.strip = strip
+ """ Used to determine if the associated field's value exists within the specified list. """
+
+ list = []
+ """ A list that contains items that may, or may not, include the given field value. """
+
+ strip = False
+ """ Determines whether to strip whitespace from either side of the given field value. """
+
+ def __init__(self, list, strip = False, error = None):
+ """ Constructor that instantiates a class instance and properties.
- def run(self, field_value):
- if (field_value.strip() if self.strip else field_value) not in self.list:
- if not self.error:
- self.error = "Value of `%s` is not within the list" % field_value
- return False
- return True
+ Keyword arguments:
+ list list -- List containing values to evaluate.
+ strip bool -- Used to strip whitespace from the given field value. (optional)
+ error str -- A user-defined error messaged for a failed rule. (optional)
+ """
+ super(IsInList, self).__init__(error)
+ self.list = list
+ self.strip = strip
+ def run(self, field_value):
+ """ Checks if field_value is included within self.list.
+
+ Keyword arguments:
+ field_value str -- the value of the associated field to compare
+ """
+
+ if (field_value.strip() if self.strip else field_value) not in self.list:
+ if not self.error:
+ self.error = "Value of `%s` is not within the list" % field_value
+ return False
+ return True
-class HasKeys(Rule):
- pass
class IsType(Rule):
- type = None
- def __init__(self, type, error = None):
- super(IsType, self).__init__(error)
- self.type = type
-
- def run(self, field_value):
- if not isinstance(field_value, self.type):
- if not self.error:
- self.error = "Type of `%s` is not type of `%s`" % (type(field_value), self.type)
- return False
- return True
+ """ Rule that compares the associated field's value against a specified data type. """
+
+ type = None
+ """ The type to compare the field value against. """
+
+ def __init__(self, type, error = None):
+ """ Constructor that instantiates a class instance and properties.
+
+ Keyword arguments:
+ type mixed -- The type to compare the field value against.
+ error str -- A user-defined error messaged for a failed rule. (optional)
+ """
+
+ super(IsType, self).__init__(error)
+ self.type = type
+
+ def run(self, field_value):
+ """ Compares field_value against self.type.
+
+ Keyword arguments:
+ field_value str -- the value of the associated field to compare
+ """
+
+ if not isinstance(field_value, self.type):
+ if not self.error:
+ self.error = "Type of `%s` is not of type `%s`" % (type(field_value), self.type)
+ return False
+ return True

0 comments on commit 465f077

Please sign in to comment.
Something went wrong with that request. Please try again.