Skip to content

Commit

Permalink
Add basic Validation for URITemplates
Browse files Browse the repository at this point in the history
Closes #33
  • Loading branch information
sigmavirus24 committed Jul 22, 2017
1 parent 942d0b8 commit 52fa015
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 2 deletions.
43 changes: 43 additions & 0 deletions tests/test_validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Tests for the uritemplate.Validator class."""
import uritemplate
from uritemplate import exceptions

import pytest


@pytest.mark.parametrize('template', [
'https://github.com{/user}',
'https://github.com/sigmavirus24{/repository}',
'{foo}',
'?{bar}',
'https://example.com',
])
def test_valid_uris(template):
"""Verify we don't raise an exception."""
urit = uritemplate.URITemplate(template)
uritemplate.Validator().validate(urit)


@pytest.mark.parametrize('template', [
'https://github.com{/user',
'https://github.com/sigmavirus24/repository}',
'{foo}}',
'?{{bar}',
])
def test_invalid_uris(template):
"""Verify we catch invalid URITemplates."""
urit = uritemplate.URITemplate(template)
with pytest.raises(exceptions.InvalidTemplate):
uritemplate.Validator().validate(urit)


@pytest.mark.parametrize('template', [
'https://github.com{/user',
'https://github.com/sigmavirus24/repository}',
'{foo}}',
'?{{bar}',
])
def test_allow_invalid_uris(template):
"""Verify we allow invalid URITemplates."""
urit = uritemplate.URITemplate(template)
uritemplate.Validator().allow_unbalanced_braces().validate(urit)
5 changes: 3 additions & 2 deletions uritemplate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
__author__ = 'Ian Cordasco'
__license__ = 'Modified BSD or Apache License, Version 2.0'
__copyright__ = 'Copyright 2013 Ian Cordasco'
__version__ = '3.0.0'
__version__ = '3.1.0'
__version_info__ = tuple(int(i) for i in __version__.split('.') if i.isdigit())

from uritemplate.api import (
URITemplate, expand, partial, variables # noqa: E402
)
from uritemplate.validator import Validator # noqa: E402

__all__ = ('URITemplate', 'expand', 'partial', 'variables')
__all__ = ('URITemplate', 'Validator', 'expand', 'partial', 'variables')
31 changes: 31 additions & 0 deletions uritemplate/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Module containing all exceptions for the uritemplate module."""


class TemplateException(Exception):
"""Base Exception class for all uritemplate exceptions."""

pass


class InvalidTemplate(TemplateException):
"""Base class for template validation."""

message = "The URI template ({}) is invalid."

def __init__(self, uri, *args):
"""Initialize our exception."""
super(InvalidTemplate, self).__init__(self.message.format(uri, *args))
self.uri = uri


class UnbalancedBraces(InvalidTemplate):
"""The template has unbalanced braces."""

message = "The URI template ({}) has more {} braces than {} braces."

def __init__(self, uri, left_braces_count, right_braces_count):
"""Initialize our exception."""
more, less = 'left', 'right'
if left_braces_count < right_braces_count:
more, less = less, more
super(UnbalancedBraces, self).__init__(uri, more, less)
58 changes: 58 additions & 0 deletions uritemplate/validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""Module containing all the validation logic for uritemplate."""
from uritemplate import exceptions as exc


class Validator(object):
"""Provide configurable validation of URITemplate objects.
.. versionadded:: 3.1.0
.. code-block::
from uritemplate import URITemplate, Validator
"""

def __init__(self):
"""Initialize our validator."""
self.enforcing_unbalanced_braces = True

def allow_unbalanced_braces(self):
"""Allow a template to have unbalanced braces.
.. versionadded:: 3.1.0
Returns the validator instance.
"""
self.enforcing_unbalanced_braces = False
return self

def force_balanced_braces(self):
"""Force a template to have balanced braces.
.. versionadded:: 3.1.0
Returns the validator instance.
"""
self.enforcing_unbalanced_braces = True
return self

def validate(self, template):
"""Validate that a template meets the parameters.
.. versionadded:: 3.1.0
:raises: uritemplate.exceptions.InvalidTemplate
:raises: uritemplate.exceptions.UnbalancedBraces
"""
if self.enforcing_unbalanced_braces:
_enforce_balanced_braces(template)


def _enforce_balanced_braces(template):
uri = template.uri
left_braces = uri.count('{')
right_braces = uri.count('}')
if left_braces != right_braces:
raise exc.UnbalancedBraces(uri, left_braces, right_braces)

0 comments on commit 52fa015

Please sign in to comment.