summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/parameters.py69
-rw-r--r--tests/test_ipalib/test_parameters.py168
2 files changed, 235 insertions, 2 deletions
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index 5bb2e4d66..4746e7652 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -27,8 +27,6 @@ TODO:
to first name and last name)
* Add the _rule_pattern() methods to `Bytes` and `Str`
-
- * Add maxvalue, minvalue kwargs and rules to `Int` and `Float`
"""
import re
@@ -761,6 +759,39 @@ class Int(Number):
type = int
type_error = _('must be an integer')
+ kwargs = Param.kwargs + (
+ ('minvalue', int, None),
+ ('maxvalue', int, None),
+ )
+
+ def __init__(self, name, *rules, **kw):
+ super(Number, self).__init__(name, *rules, **kw)
+
+ if (self.minvalue > self.maxvalue) and (self.minvalue is not None and self.maxvalue is not None):
+ raise ValueError(
+ '%s: minvalue > maxvalue (minvalue=%r, maxvalue=%r)' % (
+ self.nice, self.minvalue, self.maxvalue)
+ )
+
+ def _rule_minvalue(self, _, value):
+ """
+ Check min constraint.
+ """
+ assert type(value) is int
+ if value < self.minvalue:
+ return _('must be at least %(minvalue)d') % dict(
+ minvalue=self.minvalue,
+ )
+
+ def _rule_maxvalue(self, _, value):
+ """
+ Check max constraint.
+ """
+ assert type(value) is int
+ if value > self.maxvalue:
+ return _('can be at most %(maxvalue)d') % dict(
+ maxvalue=self.maxvalue,
+ )
class Float(Number):
"""
@@ -770,6 +801,40 @@ class Float(Number):
type = float
type_error = _('must be a decimal number')
+ kwargs = Param.kwargs + (
+ ('minvalue', float, None),
+ ('maxvalue', float, None),
+ )
+
+ def __init__(self, name, *rules, **kw):
+ super(Number, self).__init__(name, *rules, **kw)
+
+ if (self.minvalue > self.maxvalue) and (self.minvalue is not None and self.maxvalue is not None):
+ raise ValueError(
+ '%s: minvalue > maxvalue (minvalue=%r, maxvalue=%r)' % (
+ self.nice, self.minvalue, self.maxvalue)
+ )
+
+ def _rule_minvalue(self, _, value):
+ """
+ Check min constraint.
+ """
+ assert type(value) is float
+ if value < self.minvalue:
+ return _('must be at least %(minvalue)f') % dict(
+ minvalue=self.minvalue,
+ )
+
+ def _rule_maxvalue(self, _, value):
+ """
+ Check max constraint.
+ """
+ assert type(value) is float
+ if value > self.maxvalue:
+ return _('can be at most %(maxvalue)f') % dict(
+ maxvalue=self.maxvalue,
+ )
+
class Data(Param):
"""
diff --git a/tests/test_ipalib/test_parameters.py b/tests/test_ipalib/test_parameters.py
index 816f24c94..472386da3 100644
--- a/tests/test_ipalib/test_parameters.py
+++ b/tests/test_ipalib/test_parameters.py
@@ -1058,6 +1058,174 @@ class test_StrEnum(ClassChecker):
dummy.reset()
+class test_Number(ClassChecker):
+ """
+ Test the `ipalib.parameters.Number` class.
+ """
+ _cls = parameters.Number
+
+ def test_init(self):
+ """
+ Test the `ipalib.parameters.Number.__init__` method.
+ """
+ o = self.cls('my_number')
+ assert o.type is NoneType
+ assert o.password is False
+ assert o.rules == tuple()
+ assert o.class_rules == tuple()
+ assert o.all_rules == tuple()
+
+
+
+class test_Int(ClassChecker):
+ """
+ Test the `ipalib.parameters.Int` class.
+ """
+ _cls = parameters.Int
+
+ def test_init(self):
+ """
+ Test the `ipalib.parameters.Int.__init__` method.
+ """
+ # Test with no kwargs:
+ o = self.cls('my_number')
+ assert o.type is int
+ assert isinstance(o, parameters.Int)
+ assert o.minvalue is None
+ assert o.maxvalue is None
+
+ # Test when min > max:
+ e = raises(ValueError, self.cls, 'my_number', minvalue=22, maxvalue=15)
+ assert str(e) == \
+ "Int('my_number'): minvalue > maxvalue (minvalue=22, maxvalue=15)"
+
+ def test_rule_minvalue(self):
+ """
+ Test the `ipalib.parameters.Int._rule_minvalue` method.
+ """
+ o = self.cls('my_number', minvalue=3)
+ assert o.minvalue == 3
+ rule = o._rule_minvalue
+ translation = u'minvalue=%(minvalue)r'
+ dummy = dummy_ugettext(translation)
+ assert dummy.translation is translation
+
+ # Test with passing values:
+ for value in (4, 99, 1001):
+ assert rule(dummy, value) is None
+ assert dummy.called() is False
+
+ # Test with failing values:
+ for value in (-1, 0, 2):
+ assert_equal(
+ rule(dummy, value),
+ translation % dict(minvalue=3)
+ )
+ assert dummy.message == 'must be at least %(minvalue)d'
+ assert dummy.called() is True
+ dummy.reset()
+
+ def test_rule_maxvalue(self):
+ """
+ Test the `ipalib.parameters.Int._rule_maxvalue` method.
+ """
+ o = self.cls('my_number', maxvalue=4)
+ assert o.maxvalue == 4
+ rule = o._rule_maxvalue
+ translation = u'maxvalue=%(maxvalue)r'
+ dummy = dummy_ugettext(translation)
+ assert dummy.translation is translation
+
+ # Test with passing values:
+ for value in (-1, 0, 4):
+ assert rule(dummy, value) is None
+ assert dummy.called() is False
+
+ # Test with failing values:
+ for value in (5, 99, 1009):
+ assert_equal(
+ rule(dummy, value),
+ translation % dict(maxvalue=4)
+ )
+ assert dummy.message == 'can be at most %(maxvalue)d'
+ assert dummy.called() is True
+ dummy.reset()
+
+class test_Float(ClassChecker):
+ """
+ Test the `ipalib.parameters.Float` class.
+ """
+ _cls = parameters.Float
+
+ def test_init(self):
+ """
+ Test the `ipalib.parameters.Float.__init__` method.
+ """
+ # Test with no kwargs:
+ o = self.cls('my_number')
+ assert o.type is float
+ assert isinstance(o, parameters.Float)
+ assert o.minvalue is None
+ assert o.maxvalue is None
+
+ # Test when min > max:
+ e = raises(ValueError, self.cls, 'my_number', minvalue=22.5, maxvalue=15.1)
+ assert str(e) == \
+ "Float('my_number'): minvalue > maxvalue (minvalue=22.5, maxvalue=15.1)"
+
+ def test_rule_minvalue(self):
+ """
+ Test the `ipalib.parameters.Float._rule_minvalue` method.
+ """
+ o = self.cls('my_number', minvalue=3.1)
+ assert o.minvalue == 3.1
+ rule = o._rule_minvalue
+ translation = u'minvalue=%(minvalue)r'
+ dummy = dummy_ugettext(translation)
+ assert dummy.translation is translation
+
+ # Test with passing values:
+ for value in (3.2, 99.0):
+ assert rule(dummy, value) is None
+ assert dummy.called() is False
+
+ # Test with failing values:
+ for value in (-1.2, 0.0, 3.0):
+ assert_equal(
+ rule(dummy, value),
+ translation % dict(minvalue=3.1)
+ )
+ assert dummy.message == 'must be at least %(minvalue)f'
+ assert dummy.called() is True
+ dummy.reset()
+
+ def test_rule_maxvalue(self):
+ """
+ Test the `ipalib.parameters.Float._rule_maxvalue` method.
+ """
+ o = self.cls('my_number', maxvalue=4.7)
+ assert o.maxvalue == 4.7
+ rule = o._rule_maxvalue
+ translation = u'maxvalue=%(maxvalue)r'
+ dummy = dummy_ugettext(translation)
+ assert dummy.translation is translation
+
+ # Test with passing values:
+ for value in (-1.0, 0.1, 4.2):
+ assert rule(dummy, value) is None
+ assert dummy.called() is False
+
+ # Test with failing values:
+ for value in (5.3, 99.9):
+ assert_equal(
+ rule(dummy, value),
+ translation % dict(maxvalue=4.7)
+ )
+ assert dummy.message == 'can be at most %(maxvalue)f'
+ assert dummy.called() is True
+ dummy.reset()
+
+
def test_create_param():
"""
Test the `ipalib.parameters.create_param` function.