diff options
author | Martin Kosek <mkosek@redhat.com> | 2012-06-07 09:25:19 +0200 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2012-06-17 21:59:54 -0400 |
commit | 1484ccc4049dc42a5a8a71713253894ade401573 (patch) | |
tree | af2a2f2ed6ec5444095f74a36be13dc2ac145aa7 /tests | |
parent | 8f051c978e2a3cf40ba6cc9c84652ae049d978ab (diff) | |
download | freeipa-1484ccc4049dc42a5a8a71713253894ade401573.tar.gz freeipa-1484ccc4049dc42a5a8a71713253894ade401573.tar.xz freeipa-1484ccc4049dc42a5a8a71713253894ade401573.zip |
Decimal parameter conversion and normalization
Parameter Decimal does not have a sufficient value checks. Some values
cause Decimal parameter with a custom precision to crash with
an unhandled exception.
Improve parameter conversion and normalization operations to handle
decimal exceptions more gracefully. Decimal parameter now also has
new attributes enabling 2 new validation/normalization methods:
* exponential: when False, decimal number is normalized to its
non-exponential form
* numberclass: a set of allowed decimal number classes
(e.g. +Infinity, -Normal, ...) that are enforced
for every Decimal parameter value
https://fedorahosted.org/freeipa/ticket/2705
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test_ipalib/test_parameters.py | 93 |
1 files changed, 92 insertions, 1 deletions
diff --git a/tests/test_ipalib/test_parameters.py b/tests/test_ipalib/test_parameters.py index fc9569e73..0b6fae375 100644 --- a/tests/test_ipalib/test_parameters.py +++ b/tests/test_ipalib/test_parameters.py @@ -32,7 +32,7 @@ from tests.util import dummy_ugettext, assert_equal from tests.data import binary_bytes, utf8_bytes, unicode_str from ipalib import parameters, text, errors, config from ipalib.constants import TYPE_ERROR, CALLABLE_ERROR, NULLS -from ipalib.errors import ValidationError +from ipalib.errors import ValidationError, ConversionError from ipalib import _ from xmlrpclib import MAXINT, MININT @@ -1358,6 +1358,97 @@ class test_Decimal(ClassChecker): assert dummy.called() is True dummy.reset() + def test_precision(self): + """ + Test the `ipalib.parameters.Decimal` precision attribute + """ + # precission is None + param = self.cls('my_number') + + for value in (Decimal('0'), Decimal('4.4'), Decimal('4.67')): + assert_equal( + param(value), + value) + + # precision is 0 + param = self.cls('my_number', precision=0) + for original,expected in ((Decimal('0'), '0'), + (Decimal('1.1'), '1'), + (Decimal('4.67'), '5')): + assert_equal( + str(param(original)), + expected) + + # precision is 1 + param = self.cls('my_number', precision=1) + for original,expected in ((Decimal('0'), '0.0'), + (Decimal('1.1'), '1.1'), + (Decimal('4.67'), '4.7')): + assert_equal( + str(param(original)), + expected) + + # value has too many digits + param = self.cls('my_number', precision=1) + e = raises(ConversionError, param, '123456789012345678901234567890') + + assert str(e) == \ + "invalid 'my_number': quantize result has too many digits for current context" + + def test_exponential(self): + """ + Test the `ipalib.parameters.Decimal` exponential attribute + """ + param = self.cls('my_number', exponential=True) + for original,expected in ((Decimal('0'), '0'), + (Decimal('1E3'), '1E+3'), + (Decimal('3.4E2'), '3.4E+2')): + assert_equal( + str(param(original)), + expected) + + + param = self.cls('my_number', exponential=False) + for original,expected in ((Decimal('0'), '0'), + (Decimal('1E3'), '1000'), + (Decimal('3.4E2'), '340')): + assert_equal( + str(param(original)), + expected) + + def test_numberclass(self): + """ + Test the `ipalib.parameters.Decimal` numberclass attribute + """ + # test default value: '-Normal', '+Zero', '+Normal' + param = self.cls('my_number') + for value,raises_verror in ((Decimal('0'), False), + (Decimal('-0'), True), + (Decimal('1E8'), False), + (Decimal('-1.1'), False), + (Decimal('-Infinity'), True), + (Decimal('+Infinity'), True), + (Decimal('NaN'), True)): + if raises_verror: + raises(ValidationError, param, value) + else: + param(value) + + + param = self.cls('my_number', exponential=True, + numberclass=('-Normal', '+Zero', '+Infinity')) + for value,raises_verror in ((Decimal('0'), False), + (Decimal('-0'), True), + (Decimal('1E8'), True), + (Decimal('-1.1'), False), + (Decimal('-Infinity'), True), + (Decimal('+Infinity'), False), + (Decimal('NaN'), True)): + if raises_verror: + raises(ValidationError, param, value) + else: + param(value) + class test_AccessTime(ClassChecker): """ Test the `ipalib.parameters.AccessTime` class. |