summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/__init__.py2
-rw-r--r--ipalib/parameters.py41
-rw-r--r--tests/test_ipalib/test_parameters.py49
3 files changed, 91 insertions, 1 deletions
diff --git a/ipalib/__init__.py b/ipalib/__init__.py
index e5aa65d60..8abb90292 100644
--- a/ipalib/__init__.py
+++ b/ipalib/__init__.py
@@ -875,7 +875,7 @@ from backend import Backend, Context
from frontend import Command, LocalOrRemote, Application
from frontend import Object, Method, Property
from parameters import DefaultFrom, Bool, Flag, Int, Float, Bytes, Str, Password
-
+from parameters import BytesEnum, StrEnum
def create_api(mode='dummy'):
"""
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index fd693e71d..0d764d60a 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -898,6 +898,47 @@ class Password(Str):
"""
+class Enum(Param):
+ """
+ Base class for parameters with enumerable values.
+ """
+
+ kwargs = Param.kwargs + (
+ ('values', tuple, tuple()),
+ )
+
+ def __init__(self, name, *rules, **kw):
+ super(Enum, self).__init__(name, *rules, **kw)
+ for (i, v) in enumerate(self.values):
+ if type(v) is not self.type:
+ n = '%s values[%d]' % (self.nice, i)
+ raise TypeError(
+ TYPE_ERROR % (n, self.type, v, type(v))
+ )
+
+ def _rule_values(self, _, value, **kw):
+ if value not in self.values:
+ return _('must be one of %(values)r') % dict(
+ values=self.values,
+ )
+
+
+class BytesEnum(Enum):
+ """
+ Enumerable for binary data (stored in the ``str`` type).
+ """
+
+ type = unicode
+
+
+class StrEnum(Enum):
+ """
+ Enumerable for Unicode text (stored in the ``unicode`` type).
+ """
+
+ type = unicode
+
+
def create_param(spec):
"""
Create an `Str` instance from the shorthand ``spec``.
diff --git a/tests/test_ipalib/test_parameters.py b/tests/test_ipalib/test_parameters.py
index f9e370fe0..e6868d0db 100644
--- a/tests/test_ipalib/test_parameters.py
+++ b/tests/test_ipalib/test_parameters.py
@@ -898,6 +898,55 @@ class test_Str(ClassChecker):
dummy.reset()
+class test_StrEnum(ClassChecker):
+ """
+ Test the `ipalib.parameters.StrEnum` class.
+ """
+ _cls = parameters.StrEnum
+
+ def test_init(self):
+ """
+ Test the `ipalib.parameters.StrEnum.__init__` method.
+ """
+ values = (u'Hello', u'naughty', u'nurse!')
+ o = self.cls('my_strenum', values=values)
+ assert o.type is unicode
+ assert o.values is values
+ assert o.class_rules == (o._rule_values,)
+ assert o.rules == tuple()
+ assert o.all_rules == (o._rule_values,)
+
+ badvalues = (u'Hello', 'naughty', u'nurse!')
+ e = raises(TypeError, self.cls, 'my_enum', values=badvalues)
+ assert str(e) == TYPE_ERROR % (
+ "StrEnum('my_enum') values[1]", unicode, 'naughty', str
+ )
+
+ def test_rules_values(self):
+ """
+ Test the `ipalib.parameters.StrEnum._rule_values` method.
+ """
+ values = (u'Hello', u'naughty', u'nurse!')
+ o = self.cls('my_enum', values=values)
+ rule = o._rule_values
+ translation = u'values=%(values)s'
+ dummy = dummy_ugettext(translation)
+
+ # Test with passing values:
+ for v in values:
+ assert rule(dummy, v) is None
+ assert dummy.called() is False
+
+ # Test with failing values:
+ for val in (u'Howdy', u'quiet', u'library!'):
+ assert_equal(
+ rule(dummy, val),
+ translation % dict(values=values),
+ )
+ assert_equal(dummy.message, 'must be one of %(values)r')
+ dummy.reset()
+
+
def test_create_param():
"""
Test the `ipalib.parameters.create_param` function.