From 2330b2b92e96364df2da0a6f66903adf3c71da2c Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Mon, 28 Apr 2014 15:31:06 -0400 Subject: [PATCH 01/12] [#1692] fix int_validator --- ckan/logic/validators.py | 45 +++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/ckan/logic/validators.py b/ckan/logic/validators.py index 96235542c97..8beaea0f72a 100644 --- a/ckan/logic/validators.py +++ b/ckan/logic/validators.py @@ -62,14 +62,45 @@ def package_id_not_changed(value, context): return value def int_validator(value, context): - if isinstance(value, int): - return value + """ + Return an integer for value, which may be a string in base 10 or + a numeric type (e.g. int, long, float, Decimal, Fraction). Return + None for None or empty string values. + + :raises: ckan.lib.navl.dictization_functions.Invalid for other + inputs or non-whole values + + >>> int_validator("42", {}) + 42 + >>> int_validator(823764982376498236, {}) + 823764982376498236L + >>> int_validator("", {}) is None + True + >>> int_validator(None, {}) is None + True + >>> int_validator("not a number", {}) + Traceback (most recent call last): + ... + Invalid('Invalid integer') + >>> int_validator(19.5, {}) + Traceback (most recent call last): + ... + Invalid('Invalid integer') + """ + if value is None or value == '': + return None + try: - if value.strip() == '': - return None - return int(value) - except (AttributeError, ValueError), e: - raise Invalid(_('Invalid integer')) + whole, part = divmod(value, 1) + except TypeError: + try: + return int(value) + except ValueError: + pass + else: + return int(whole) + + raise Invalid(_('Invalid integer')) def natural_number_validator(value, context): value = int_validator(value, context) From a9efd8afe0dca187a73fea78209c50b6261c723c Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Mon, 28 Apr 2014 16:20:14 -0400 Subject: [PATCH 02/12] [#1692] int_validator: accept all-whitespace for backwards compat. --- ckan/logic/validators.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ckan/logic/validators.py b/ckan/logic/validators.py index 8beaea0f72a..a63b90fb0c1 100644 --- a/ckan/logic/validators.py +++ b/ckan/logic/validators.py @@ -65,7 +65,7 @@ def int_validator(value, context): """ Return an integer for value, which may be a string in base 10 or a numeric type (e.g. int, long, float, Decimal, Fraction). Return - None for None or empty string values. + None for None or empty/all-whitespace string values. :raises: ckan.lib.navl.dictization_functions.Invalid for other inputs or non-whole values @@ -74,7 +74,7 @@ def int_validator(value, context): 42 >>> int_validator(823764982376498236, {}) 823764982376498236L - >>> int_validator("", {}) is None + >>> int_validator(" ", {}) is None True >>> int_validator(None, {}) is None True @@ -87,7 +87,9 @@ def int_validator(value, context): ... Invalid('Invalid integer') """ - if value is None or value == '': + if value is None: + return None + if hasattr(value, 'strip') and not value.strip(): return None try: From 3b0bae973ca59ced4b0a1466a9c2a24401d2f49d Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Mon, 28 Apr 2014 16:53:18 -0400 Subject: [PATCH 03/12] [#1692] add tests for int_validator --- ckan/new_tests/logic/test_validators.py | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/ckan/new_tests/logic/test_validators.py b/ckan/new_tests/logic/test_validators.py index 42d8013112e..b7fc908e192 100644 --- a/ckan/new_tests/logic/test_validators.py +++ b/ckan/new_tests/logic/test_validators.py @@ -16,6 +16,9 @@ import ckan.new_tests.lib.navl.test_validators as t +eq = nose.tools.eq_ + + def returns_arg(function): '''A decorator that tests that the decorated function returns the argument that it is called with, unmodified. @@ -444,5 +447,48 @@ def call_validator(*args, **kwargs): *args, **kwargs) call_validator(key, data, errors, context={'model': mock_model}) + def test_int_validator_idempotent(self): + unchanged_values = [ + 42, + 0, + 3948756923874659827346598, + None, + ] + for v in unchanged_values: + returns_arg(validators.int_validator)(v) + + def test_int_validator_convert(self): + from fractions import Fraction + from decimal import Decimal + + converted_values = [ + (42.0, 42), + (Fraction(2, 1), 2), + (Decimal("19.00", 19)), + ("528735648764587235684376", 528735648764587235684376), + ("", None), + (" \n", None), + (1 + 0j, 1), + ] + for arg, result in converted_values: + eq(validators.int_validator(arg), result) + + def test_int_validator_invalid(self): + from fractions import Fraction + from decimal import Decimal + + invalid_values = [ + 42.5, + "42.5", + "1e6", + "text", + Fraction(3, 2), + Decimal("19.99"), + 1 + 1j, + ] + for v in invalid_values: + raises_Invalid(validators.int_validator)(v) + + #TODO: Need to test when you are not providing owner_org and the validator # queries for the dataset with package_show From 9a0f6d3feaa73f2ed832012f03cc64aa55c89e00 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Mon, 28 Apr 2014 17:26:47 -0400 Subject: [PATCH 04/12] [#1692] fix int_validator tests and non-whole handling --- ckan/logic/validators.py | 6 +++++- ckan/new_tests/logic/test_validators.py | 10 +++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ckan/logic/validators.py b/ckan/logic/validators.py index a63b90fb0c1..8867defbaa1 100644 --- a/ckan/logic/validators.py +++ b/ckan/logic/validators.py @@ -100,7 +100,11 @@ def int_validator(value, context): except ValueError: pass else: - return int(whole) + if not part: + try: + return int(whole) + except TypeError: + pass # complex number: fail like int(complex) does raise Invalid(_('Invalid integer')) diff --git a/ckan/new_tests/logic/test_validators.py b/ckan/new_tests/logic/test_validators.py index b7fc908e192..eacfd3b5b60 100644 --- a/ckan/new_tests/logic/test_validators.py +++ b/ckan/new_tests/logic/test_validators.py @@ -448,6 +448,8 @@ def call_validator(*args, **kwargs): call_validator(key, data, errors, context={'model': mock_model}) def test_int_validator_idempotent(self): + import ckan.logic.validators as validators + unchanged_values = [ 42, 0, @@ -458,6 +460,7 @@ def test_int_validator_idempotent(self): returns_arg(validators.int_validator)(v) def test_int_validator_convert(self): + import ckan.logic.validators as validators from fractions import Fraction from decimal import Decimal @@ -468,12 +471,12 @@ def test_int_validator_convert(self): ("528735648764587235684376", 528735648764587235684376), ("", None), (" \n", None), - (1 + 0j, 1), ] for arg, result in converted_values: - eq(validators.int_validator(arg), result) + eq(validators.int_validator(arg, None), result) def test_int_validator_invalid(self): + import ckan.logic.validators as validators from fractions import Fraction from decimal import Decimal @@ -485,9 +488,10 @@ def test_int_validator_invalid(self): Fraction(3, 2), Decimal("19.99"), 1 + 1j, + 1 + 0j, # int(complex) fails, so expect the same ] for v in invalid_values: - raises_Invalid(validators.int_validator)(v) + raises_Invalid(validators.int_validator)(v, None) #TODO: Need to test when you are not providing owner_org and the validator From f027022f0a212d8988d16fdd1d17a7788144df4d Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Mon, 28 Apr 2014 17:29:05 -0400 Subject: [PATCH 05/12] [#1692] remove doc tests --- ckan/logic/validators.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/ckan/logic/validators.py b/ckan/logic/validators.py index 8867defbaa1..598ac0b6e7c 100644 --- a/ckan/logic/validators.py +++ b/ckan/logic/validators.py @@ -69,23 +69,6 @@ def int_validator(value, context): :raises: ckan.lib.navl.dictization_functions.Invalid for other inputs or non-whole values - - >>> int_validator("42", {}) - 42 - >>> int_validator(823764982376498236, {}) - 823764982376498236L - >>> int_validator(" ", {}) is None - True - >>> int_validator(None, {}) is None - True - >>> int_validator("not a number", {}) - Traceback (most recent call last): - ... - Invalid('Invalid integer') - >>> int_validator(19.5, {}) - Traceback (most recent call last): - ... - Invalid('Invalid integer') """ if value is None: return None From 0d00ac2b677f635c3ae68510718f6dafcb3bd04e Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Mon, 28 Apr 2014 21:16:49 -0400 Subject: [PATCH 06/12] [#1692] fix int_validator tests more --- ckan/new_tests/logic/test_validators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ckan/new_tests/logic/test_validators.py b/ckan/new_tests/logic/test_validators.py index eacfd3b5b60..c7a8fa663e2 100644 --- a/ckan/new_tests/logic/test_validators.py +++ b/ckan/new_tests/logic/test_validators.py @@ -467,7 +467,7 @@ def test_int_validator_convert(self): converted_values = [ (42.0, 42), (Fraction(2, 1), 2), - (Decimal("19.00", 19)), + (Decimal("19.00"), 19), ("528735648764587235684376", 528735648764587235684376), ("", None), (" \n", None), @@ -488,7 +488,7 @@ def test_int_validator_invalid(self): Fraction(3, 2), Decimal("19.99"), 1 + 1j, - 1 + 0j, # int(complex) fails, so expect the same + 1 + 0j, # int(complex) fails, so expect the same ] for v in invalid_values: raises_Invalid(validators.int_validator)(v, None) From f1ebce120953dd2ccf281b9739d2a33ae6e3b562 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Mon, 28 Apr 2014 21:33:49 -0400 Subject: [PATCH 07/12] [#1692] suppress DeprecationWarning on test of invalid data to int_validator --- ckan/new_tests/logic/test_validators.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ckan/new_tests/logic/test_validators.py b/ckan/new_tests/logic/test_validators.py index c7a8fa663e2..8717a4b40d6 100644 --- a/ckan/new_tests/logic/test_validators.py +++ b/ckan/new_tests/logic/test_validators.py @@ -479,6 +479,7 @@ def test_int_validator_invalid(self): import ckan.logic.validators as validators from fractions import Fraction from decimal import Decimal + import warnings invalid_values = [ 42.5, @@ -490,8 +491,10 @@ def test_int_validator_invalid(self): 1 + 1j, 1 + 0j, # int(complex) fails, so expect the same ] - for v in invalid_values: - raises_Invalid(validators.int_validator)(v, None) + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + for v in invalid_values: + raises_Invalid(validators.int_validator)(v, None) #TODO: Need to test when you are not providing owner_org and the validator From d94ae913fed9f34b0ee6ea2ebb1fb541ebd35757 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Wed, 30 Apr 2014 10:52:35 -0400 Subject: [PATCH 08/12] [#1692] use assert_equals --- ckan/new_tests/logic/test_validators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ckan/new_tests/logic/test_validators.py b/ckan/new_tests/logic/test_validators.py index 8717a4b40d6..784c2ef9053 100644 --- a/ckan/new_tests/logic/test_validators.py +++ b/ckan/new_tests/logic/test_validators.py @@ -16,7 +16,7 @@ import ckan.new_tests.lib.navl.test_validators as t -eq = nose.tools.eq_ +assert_equals = nose.tools.assert_equals def returns_arg(function): @@ -473,7 +473,7 @@ def test_int_validator_convert(self): (" \n", None), ] for arg, result in converted_values: - eq(validators.int_validator(arg, None), result) + assert_equals(validators.int_validator(arg, None), result) def test_int_validator_invalid(self): import ckan.logic.validators as validators From 6ca20c79f748b2374702b88f0bf3b615afa9840c Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Thu, 1 May 2014 16:17:46 -0400 Subject: [PATCH 09/12] [#1692] coding standards: single quotes --- ckan/logic/validators.py | 38 ++++++++++++------------- ckan/new_tests/logic/test_validators.py | 18 ++++++------ 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/ckan/logic/validators.py b/ckan/logic/validators.py index 598ac0b6e7c..26bb2fd3b95 100644 --- a/ckan/logic/validators.py +++ b/ckan/logic/validators.py @@ -62,14 +62,14 @@ def package_id_not_changed(value, context): return value def int_validator(value, context): - """ + ''' Return an integer for value, which may be a string in base 10 or a numeric type (e.g. int, long, float, Decimal, Fraction). Return None for None or empty/all-whitespace string values. :raises: ckan.lib.navl.dictization_functions.Invalid for other inputs or non-whole values - """ + ''' if value is None: return None if hasattr(value, 'strip') and not value.strip(): @@ -174,10 +174,10 @@ def package_id_or_name_exists(package_id_or_name, context): return package_id_or_name def user_id_exists(user_id, context): - """Raises Invalid if the given user_id does not exist in the model given + '''Raises Invalid if the given user_id does not exist in the model given in the context, otherwise returns the given user_id. - """ + ''' model = context['model'] session = context['session'] @@ -204,10 +204,10 @@ def user_id_or_name_exists(user_id_or_name, context): return user_id_or_name def group_id_exists(group_id, context): - """Raises Invalid if the given group_id does not exist in the model given + '''Raises Invalid if the given group_id does not exist in the model given in the context, otherwise returns the given group_id. - """ + ''' model = context['model'] session = context['session'] @@ -218,10 +218,10 @@ def group_id_exists(group_id, context): def related_id_exists(related_id, context): - """Raises Invalid if the given related_id does not exist in the model + '''Raises Invalid if the given related_id does not exist in the model given in the context, otherwise returns the given related_id. - """ + ''' model = context['model'] session = context['session'] @@ -231,9 +231,9 @@ def related_id_exists(related_id, context): return related_id def group_id_or_name_exists(reference, context): - """ + ''' Raises Invalid if a group identified by the name or id cannot be found. - """ + ''' model = context['model'] result = model.Group.get(reference) if not result: @@ -241,13 +241,13 @@ def group_id_or_name_exists(reference, context): return reference def activity_type_exists(activity_type): - """Raises Invalid if there is no registered activity renderer for the + '''Raises Invalid if there is no registered activity renderer for the given activity_type. Otherwise returns the given activity_type. This just uses object_id_validators as a lookup. very safe. - """ + ''' if activity_type in object_id_validators: return activity_type else: @@ -286,7 +286,7 @@ def resource_id_exists(value, context): } def object_id_validator(key, activity_dict, errors, context): - """Validate the 'object_id' value of an activity_dict. + '''Validate the 'object_id' value of an activity_dict. Uses the object_id_validators dict (above) to find and call an 'object_id' validator function for the given activity_dict's 'activity_type' value. @@ -298,7 +298,7 @@ def object_id_validator(key, activity_dict, errors, context): Raises Invalid if there is no object_id_validator for the activity_dict's 'activity_type' value. - """ + ''' activity_type = activity_dict[('activity_type',)] if object_id_validators.has_key(activity_type): object_id = activity_dict[('object_id',)] @@ -348,15 +348,15 @@ def name_validator(value, context): return value def package_name_validator(key, data, errors, context): - model = context["model"] - session = context["session"] - package = context.get("package") + model = context['model'] + session = context['session'] + package = context.get('package') query = session.query(model.Package.name).filter_by(name=data[key]) if package: package_id = package.id else: - package_id = data.get(key[:-1] + ("id",)) + package_id = data.get(key[:-1] + ('id',)) if package_id and package_id is not missing: query = query.filter(model.Package.id <> package_id) result = query.first() @@ -676,7 +676,7 @@ def tag_not_in_vocabulary(key, tag_dict, errors, context): return def url_validator(key, data, errors, context): - """ Checks that the provided value (if it is present) is a valid URL """ + ''' Checks that the provided value (if it is present) is a valid URL ''' import urlparse import string diff --git a/ckan/new_tests/logic/test_validators.py b/ckan/new_tests/logic/test_validators.py index 784c2ef9053..a878eacd669 100644 --- a/ckan/new_tests/logic/test_validators.py +++ b/ckan/new_tests/logic/test_validators.py @@ -467,10 +467,10 @@ def test_int_validator_convert(self): converted_values = [ (42.0, 42), (Fraction(2, 1), 2), - (Decimal("19.00"), 19), - ("528735648764587235684376", 528735648764587235684376), - ("", None), - (" \n", None), + (Decimal('19.00'), 19), + ('528735648764587235684376', 528735648764587235684376), + ('', None), + (' \n', None), ] for arg, result in converted_values: assert_equals(validators.int_validator(arg, None), result) @@ -483,16 +483,16 @@ def test_int_validator_invalid(self): invalid_values = [ 42.5, - "42.5", - "1e6", - "text", + '42.5', + '1e6', + 'text', Fraction(3, 2), - Decimal("19.99"), + Decimal('19.99'), 1 + 1j, 1 + 0j, # int(complex) fails, so expect the same ] with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=DeprecationWarning) + warnings.filterwarnings('ignore', category=DeprecationWarning) for v in invalid_values: raises_Invalid(validators.int_validator)(v, None) From 74dc38e902d084441d22ba0ae39481e7cc5fa3c6 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Thu, 1 May 2014 16:23:57 -0400 Subject: [PATCH 10/12] [#1692] coding standards: imports at top --- ckan/new_tests/logic/test_validators.py | 59 +++++-------------------- 1 file changed, 12 insertions(+), 47 deletions(-) diff --git a/ckan/new_tests/logic/test_validators.py b/ckan/new_tests/logic/test_validators.py index a878eacd669..fbb4482a30b 100644 --- a/ckan/new_tests/logic/test_validators.py +++ b/ckan/new_tests/logic/test_validators.py @@ -3,6 +3,9 @@ ''' import copy +import fractions +import decimal +import warnings import mock import nose.tools @@ -14,7 +17,9 @@ # different places in the code) we have to either do this or introduce a shared # test helper functions module (which we also don't want to do). import ckan.new_tests.lib.navl.test_validators as t - +import ckan.lib.navl.dictization_functions as df +import ckan.logic.validators as validators +import ckan.model as model assert_equals = nose.tools.assert_equals @@ -58,7 +63,6 @@ def call_validator(*args, **kwargs): ''' def call_and_assert(*args, **kwargs): - import ckan.lib.navl.dictization_functions as df nose.tools.assert_raises(df.Invalid, function, *args, **kwargs) return call_and_assert @@ -147,9 +151,6 @@ def test_name_validator_with_invalid_value(self): '''If given an invalid value name_validator() should do raise Invalid. ''' - import ckan.logic.validators as validators - import ckan.model as model - invalid_values = [ # Non-string names aren't allowed as names. 13, @@ -201,9 +202,6 @@ def test_name_validator_with_valid_value(self): return the string. ''' - import ckan.logic.validators as validators - import ckan.model as model - valid_names = [ 'fred', 'fred-flintstone', @@ -232,8 +230,6 @@ def test_user_name_validator_with_non_string_value(self): value. ''' - import ckan.logic.validators as validators - non_string_values = [ 13, 23.7, @@ -273,8 +269,6 @@ def test_user_name_validator_with_a_name_that_already_exists(self): user name that already exists. ''' - import ckan.logic.validators as validators - # Mock ckan.model. model.User.get('user_name') will return another mock # object rather than None, which will simulate an existing user with # the same user name in the database. @@ -296,9 +290,6 @@ def call_validator(*args, **kwargs): def test_user_name_validator_successful(self): '''user_name_validator() should do nothing if given a valid name.''' - - import ckan.logic.validators as validators - data = factories.validator_data_dict() key = ('name',) data[key] = 'new_user_name' @@ -322,19 +313,15 @@ def call_validator(*args, **kwargs): # the context dict. def test_if_empty_guess_format(self): - - import ckan.logic.validators as validators - import ckan.lib.navl.dictization_functions as dictization_functions - data = {'name': 'package_name', 'resources': [ {'url': 'http://fakedomain/my.csv', 'format': ''}, {'url': 'http://fakedomain/my.pdf', - 'format': dictization_functions.Missing}, + 'format': df.Missing}, {'url': 'http://fakedomain/my.pdf', 'format': 'pdf'}, {'url': 'http://fakedomain/my.pdf', 'id': 'fake_resource_id', 'format': ''} ]} - data = dictization_functions.flatten_dict(data) + data = df.flatten_dict(data) @t.does_not_modify_errors_dict def call_validator(*args, **kwargs): @@ -361,8 +348,6 @@ def call_validator(*args, **kwargs): assert new_data[('resources', 3, 'format')] == '' def test_clean_format(self): - import ckan.logic.validators as validators - format = validators.clean_format('csv') assert format == 'CSV' @@ -376,9 +361,6 @@ def test_clean_format(self): assert format == '' def test_datasets_with_org_can_be_private_when_creating(self): - - import ckan.logic.validators as validators - data = factories.validator_data_dict() errors = factories.validator_errors_dict() @@ -400,9 +382,6 @@ def call_validator(*args, **kwargs): call_validator(key, data, errors, context={'model': mock_model}) def test_datasets_with_no_org_cannot_be_private_when_creating(self): - - import ckan.logic.validators as validators - data = factories.validator_data_dict() errors = factories.validator_errors_dict() @@ -423,9 +402,6 @@ def call_validator(*args, **kwargs): call_validator(key, data, errors, context={'model': mock_model}) def test_datasets_with_org_can_be_private_when_updating(self): - - import ckan.logic.validators as validators - data = factories.validator_data_dict() errors = factories.validator_errors_dict() @@ -448,8 +424,6 @@ def call_validator(*args, **kwargs): call_validator(key, data, errors, context={'model': mock_model}) def test_int_validator_idempotent(self): - import ckan.logic.validators as validators - unchanged_values = [ 42, 0, @@ -460,14 +434,10 @@ def test_int_validator_idempotent(self): returns_arg(validators.int_validator)(v) def test_int_validator_convert(self): - import ckan.logic.validators as validators - from fractions import Fraction - from decimal import Decimal - converted_values = [ (42.0, 42), - (Fraction(2, 1), 2), - (Decimal('19.00'), 19), + (fractions.Fraction(2, 1), 2), + (decimal.Decimal('19.00'), 19), ('528735648764587235684376', 528735648764587235684376), ('', None), (' \n', None), @@ -476,18 +446,13 @@ def test_int_validator_convert(self): assert_equals(validators.int_validator(arg, None), result) def test_int_validator_invalid(self): - import ckan.logic.validators as validators - from fractions import Fraction - from decimal import Decimal - import warnings - invalid_values = [ 42.5, '42.5', '1e6', 'text', - Fraction(3, 2), - Decimal('19.99'), + fractions.Fraction(3, 2), + decimal.Decimal('19.99'), 1 + 1j, 1 + 0j, # int(complex) fails, so expect the same ] From b20be7d67cdd0c5e9c33a24c4fcf12ea8d0ad981 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Thu, 1 May 2014 16:52:26 -0400 Subject: [PATCH 11/12] [#1692] follow testing pattern proposed in #1672 --- ckan/new_tests/logic/test_validators.py | 112 ++++++++++++++++-------- 1 file changed, 75 insertions(+), 37 deletions(-) diff --git a/ckan/new_tests/logic/test_validators.py b/ckan/new_tests/logic/test_validators.py index fbb4482a30b..4a057d2a7d6 100644 --- a/ckan/new_tests/logic/test_validators.py +++ b/ckan/new_tests/logic/test_validators.py @@ -423,44 +423,82 @@ def call_validator(*args, **kwargs): *args, **kwargs) call_validator(key, data, errors, context={'model': mock_model}) - def test_int_validator_idempotent(self): - unchanged_values = [ - 42, - 0, - 3948756923874659827346598, - None, - ] - for v in unchanged_values: - returns_arg(validators.int_validator)(v) - - def test_int_validator_convert(self): - converted_values = [ - (42.0, 42), - (fractions.Fraction(2, 1), 2), - (decimal.Decimal('19.00'), 19), - ('528735648764587235684376', 528735648764587235684376), - ('', None), - (' \n', None), - ] - for arg, result in converted_values: - assert_equals(validators.int_validator(arg, None), result) - def test_int_validator_invalid(self): - invalid_values = [ - 42.5, - '42.5', - '1e6', - 'text', - fractions.Fraction(3, 2), - decimal.Decimal('19.99'), - 1 + 1j, - 1 + 0j, # int(complex) fails, so expect the same - ] - with warnings.catch_warnings(): +class TestIntValidator(object): + + def test_int_unchanged(self): + returns_arg(validators.int_validator)(42) + + def test_zero_unchanged(self): + returns_arg(validators.int_validator)(0) + + def test_long_unchanged(self): + returns_arg(validators.int_validator)(3948756923874659827346598) + + def test_None_unchanged(self): + returns_arg(validators.int_validator)(None) + + def test_float_converted(self): + assert_equals(validators.int_validator(42.0, None), 42) + + def test_fraction_converted(self): + assert_equals(validators.int_validator( + fractions.Fraction(2, 1), {}), 2) + + def test_decimal_converted(self): + assert_equals(validators.int_validator( + decimal.Decimal('19.00'), {}), 19) + + def test_long_int_string_converted(self): + assert_equals(validators.int_validator( + '528735648764587235684376', {}), 528735648764587235684376) + + def test_negative_int_string_converted(self): + assert_equals(validators.int_validator('-2', {}), -2) + + def test_positive_int_string_converted(self): + assert_equals(validators.int_validator('+3', {}), 3) + + def test_zero_prefixed_int_string_converted_as_decimal(self): + assert_equals(validators.int_validator('0123', {}), 123) + + def test_string_with_whitespace_converted(self): + assert_equals(validators.int_validator('\t 98\n', {}), 98) + + def test_empty_string_becomes_None(self): + assert_equals(validators.int_validator('', {}), None) + + def test_whitespace_string_becomes_None(self): + assert_equals(validators.int_validator('\n\n \t', {}), None) + + def test_float_with_decimal_raises_Invalid(self): + raises_Invalid(validators.int_validator)(42.5, {}) + + def test_float_string_raises_Invalid(self): + raises_Invalid(validators.int_validator)('42.0', {}) + + def test_exponent_string_raises_Invalid(self): + raises_Invalid(validators.int_validator)('1e6', {}) + + def test_non_numeric_string_raises_Invalid(self): + raises_Invalid(validators.int_validator)('text', {}) + + def test_non_whole_fraction_raises_Invalid(self): + raises_Invalid(validators.int_validator)(fractions.Fraction(3, 2), {}) + + def test_non_whole_decimal_raises_Invalid(self): + raises_Invalid(validators.int_validator)(decimal.Decimal('19.99'), {}) + + def test_complex_with_imaginary_component_raises_Invalid(self): + with warnings.catch_warnings(): # divmod() issues warning for this type + warnings.filterwarnings('ignore', category=DeprecationWarning) + raises_Invalid(validators.int_validator)(1 + 1j, {}) + + def test_complex_without_imaginary_component_raises_Invalid(self): + with warnings.catch_warnings(): # divmod() issues warning for this type warnings.filterwarnings('ignore', category=DeprecationWarning) - for v in invalid_values: - raises_Invalid(validators.int_validator)(v, None) + raises_Invalid(validators.int_validator)(1 + 0j, {}) - #TODO: Need to test when you are not providing owner_org and the validator - # queries for the dataset with package_show +#TODO: Need to test when you are not providing owner_org and the validator +# queries for the dataset with package_show From c7f654c90c242e8df673e8060ea0ec23662dd653 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Thu, 1 May 2014 17:20:27 -0400 Subject: [PATCH 12/12] [#1692] pep8 --- ckan/new_tests/logic/test_validators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ckan/new_tests/logic/test_validators.py b/ckan/new_tests/logic/test_validators.py index 4a057d2a7d6..2020afc06c7 100644 --- a/ckan/new_tests/logic/test_validators.py +++ b/ckan/new_tests/logic/test_validators.py @@ -490,12 +490,12 @@ def test_non_whole_decimal_raises_Invalid(self): raises_Invalid(validators.int_validator)(decimal.Decimal('19.99'), {}) def test_complex_with_imaginary_component_raises_Invalid(self): - with warnings.catch_warnings(): # divmod() issues warning for this type + with warnings.catch_warnings(): # divmod() issues warning for complex warnings.filterwarnings('ignore', category=DeprecationWarning) raises_Invalid(validators.int_validator)(1 + 1j, {}) def test_complex_without_imaginary_component_raises_Invalid(self): - with warnings.catch_warnings(): # divmod() issues warning for this type + with warnings.catch_warnings(): # divmod() issues warning for complex warnings.filterwarnings('ignore', category=DeprecationWarning) raises_Invalid(validators.int_validator)(1 + 0j, {})