Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .travis.yml

This file was deleted.

3 changes: 3 additions & 0 deletions filters/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.conf import settings

settings.configure()
File renamed without changes.
77 changes: 77 additions & 0 deletions filters/tests/test_validations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import unittest
from nose2.tools.such import helper
from voluptuous import Invalid
from filters import validations

INT = 1
LONG = long(INT)
INT_FLOAT = float(INT)
INT_STR = str(INT)
INT_UNICODE = unicode(INT)
ALNUM_STR = "hello123"
ALNUM_UNICODE = unicode(ALNUM_STR)
NON_INT_FLOAT = 1.5
NON_INT_STR = str(NON_INT_FLOAT)
NON_INT_UNICODE = unicode(NON_INT_FLOAT)
NON_ALNUM_STR = "hello 123"
NON_ALNUM_UNICODE = unicode(NON_ALNUM_STR)
INT_CSV = "1,2,3"
NON_INT_CSV = "a,b,c"


class BaseValidationTestCase(object):
def f(self, v):
return self.base_function()(v)

def transform_val(self, v):
return v

def test_valid_values(self):
for v in self.valid_values:
self.assertEqual(self.f(v), self.transform_val(v))

def test_invalid_values(self):
for v in self.invalid_values:
self.assertRaises(Invalid, self.f, v)


class IntegerLikeTestCase(BaseValidationTestCase, unittest.TestCase):
base_function = validations.IntegerLike
valid_values = [
INT, LONG, INT_FLOAT, INT_STR, INT_UNICODE
]
invalid_values = [
NON_INT_FLOAT, NON_INT_STR, ALNUM_STR, ALNUM_UNICODE,
NON_INT_UNICODE, NON_ALNUM_STR, NON_ALNUM_UNICODE
]


class AlphanumericTestCase(BaseValidationTestCase, unittest.TestCase):
base_function = validations.Alphanumeric
valid_values = [
INT, LONG, INT_FLOAT, INT_STR, INT_UNICODE, ALNUM_STR, ALNUM_UNICODE
]
invalid_values = [
NON_INT_FLOAT, NON_INT_STR, NON_INT_UNICODE, NON_ALNUM_STR,
NON_ALNUM_UNICODE
]


class StrictlyAlphanumericTestCase(BaseValidationTestCase, unittest.TestCase):
base_function = validations.StrictlyAlphanumeric
valid_values = [ALNUM_STR, ALNUM_UNICODE]
invalid_values = [
INT, LONG, INT_FLOAT, NON_INT_FLOAT, NON_INT_STR, NON_INT_UNICODE,
NON_ALNUM_STR, NON_ALNUM_UNICODE, INT_STR, INT_UNICODE
]


class CSVofIntegersTestCase(BaseValidationTestCase, unittest.TestCase):
base_function = validations.CSVofIntegers
transform_val = lambda self, v: map(int, v.split(","))
valid_values = [INT_CSV, INT_STR, INT_UNICODE]
invalid_values = [
INT_FLOAT, ALNUM_STR, ALNUM_UNICODE, NON_INT_FLOAT, NON_INT_STR,
NON_INT_UNICODE, NON_ALNUM_STR, NON_ALNUM_UNICODE, NON_INT_CSV,
INT, LONG
]
File renamed without changes.
49 changes: 24 additions & 25 deletions filters/validations.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# This module is define and keep all generic type of data-validations.
import six
import re
import sys
import numbers
from voluptuous import Invalid
from django.utils.dateparse import parse_datetime, parse_date

# Forward compatibility with Python 3.x
if sys.version_info.major == 3:
basestring = str


def IntegerLike(msg=None):
'''
Expand All @@ -14,13 +18,11 @@ def IntegerLike(msg=None):
- str or unicode composed only of digits
'''
def fn(value):
if not (
isinstance(value, int) or
(isinstance(value, float) and value.is_integer()) or
(isinstance(value, str) and value.isdigit()) or
((isinstance(value, unicode) and value.isdigit() or
isinstance(value, long)) if six.PY2 else None)
):
if not any([
isinstance(value, numbers.Integral),
(isinstance(value, float) and value.is_integer()),
(isinstance(value, basestring) and value.isdigit())
]):
raise Invalid(msg or (
'Invalid input <{0}>; expected an integer'.format(value))
)
Expand All @@ -38,13 +40,11 @@ def Alphanumeric(msg=None):
- str or unicode composed only of alphanumeric characters
'''
def fn(value):
if not (
isinstance(value, int) or
(isinstance(value, float) and value.is_integer()) or
(isinstance(value, str) and value.isalnum()) or
((isinstance(value, unicode) and value.isdigit() or
isinstance(value, long)) if six.PY2 else None)
):
if not any([
isinstance(value, numbers.Integral),
(isinstance(value, float) and value.is_integer()),
(isinstance(value, basestring) and value.isalnum())
]):
raise Invalid(msg or (
'Invalid input <{0}>; expected an integer'.format(value))
)
Expand All @@ -53,10 +53,6 @@ def fn(value):
return fn


re_alphabets = re.compile('[A-Za-z]')
re_digits = re.compile('[0-9]')


def StrictlyAlphanumeric(msg=None):
'''
Checks whether a value is:
Expand All @@ -65,9 +61,10 @@ def StrictlyAlphanumeric(msg=None):
'''
def fn(value):
if not (
(isinstance(value, str) or (isinstance(value, unicode) if six.PY2 else None)) and
re_alphabets.search(value) and
re_digits.search(value)
isinstance(value, basestring) and
value.isalnum() and not
value.isdigit() and not
value.isalpha()
):
raise Invalid(msg or (
'Invalid input <{0}>; expected an integer'.format(value))
Expand Down Expand Up @@ -97,12 +94,12 @@ def fn(value):
def CSVofIntegers(msg=None):
'''
Checks whether a value is list of integers.
Returns list of integers or just one integer in
Returns list of integers or just one integer in
list if there is only one element in given CSV string.
'''
def fn(value):
try:
if isinstance(value, six.text_type):
if isinstance(value, basestring):
if ',' in value:
value = list(map(
int, filter(
Expand All @@ -114,6 +111,8 @@ def fn(value):
return value
else:
return [int(value)]
else:
raise ValueError
except ValueError:
raise Invalid(
'<{0}> is not a valid csv of integers'.format(value)
Expand Down
10 changes: 6 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
packages=['filters'],
include_package_data=True,
description=(
'A django app to apply filters on drf querysets '
'using query params with validations using voluptuous.'
),
'A django app to apply filters on drf querysets '
'using query params with validations using voluptuous.'
),
long_description=README,
url=__url__,
download_url=__download_url__,
Expand All @@ -51,5 +51,7 @@
'License :: OSI Approved :: MIT License',
'Programming Language :: Python :: 2.7',
],
keywords='drf-url-filters, filters, queryparamters',
keywords='drf-url-filters, filters, queryparameters',
test_suite='nose2.collector.collector',
tests_require=['nose2'],
)
Empty file removed tests/__init__.py
Empty file.