Merge "Adds new fields and field types"

This commit is contained in:
Jenkins
2016-08-22 20:58:24 +00:00
committed by Gerrit Code Review
2 changed files with 101 additions and 0 deletions

View File

@@ -385,6 +385,15 @@ class Integer(FieldType):
return {'type': ['integer']}
class NonNegativeInteger(FieldType):
@staticmethod
def coerce(obj, attr, value):
v = int(value)
if v < 0:
raise ValueError(_('Value must be >= 0 for field %s') % attr)
return v
class Float(FieldType):
def coerce(self, obj, attr, value):
return float(value)
@@ -393,6 +402,15 @@ class Float(FieldType):
return {'type': ['number']}
class NonNegativeFloat(FieldType):
@staticmethod
def coerce(obj, attr, value):
v = float(value)
if v < 0:
raise ValueError(_('Value must be >= 0 for field %s') % attr)
return v
class Boolean(FieldType):
@staticmethod
def coerce(obj, attr, value):
@@ -482,6 +500,17 @@ class IPV6Address(IPAddress):
return result
class IPV4AndV6Address(IPAddress):
@staticmethod
def coerce(obj, attr, value):
result = IPAddress.coerce(obj, attr, value)
if result.version != 4 and result.version != 6:
raise ValueError(_('Network "%(val)s" is not valid '
'in field %(attr)s') %
{'val': value, 'attr': attr})
return result
class IPNetwork(IPAddress):
@staticmethod
def coerce(obj, attr, value):
@@ -898,10 +927,18 @@ class IntegerField(AutoTypedField):
AUTO_TYPE = Integer()
class NonNegativeIntegerField(AutoTypedField):
AUTO_TYPE = NonNegativeInteger()
class FloatField(AutoTypedField):
AUTO_TYPE = Float()
class NonNegativeFloatField(AutoTypedField):
AUTO_TYPE = NonNegativeFloat()
# This is a strict interpretation of boolean
# values using Python's semantics for truth/falsehood
class BooleanField(AutoTypedField):
@@ -968,6 +1005,10 @@ class ListOfSetsOfIntegersField(AutoTypedField):
AUTO_TYPE = List(Set(Integer()))
class ListOfIntegersField(AutoTypedField):
AUTO_TYPE = List(Integer())
class ListOfDictOfNullableStringsField(AutoTypedField):
AUTO_TYPE = List(Dict(String(), nullable=True))
@@ -998,6 +1039,10 @@ class IPV6AddressField(AutoTypedField):
AUTO_TYPE = IPV6Address()
class IPV4AndV6AddressField(AutoTypedField):
AUTO_TYPE = IPV4AndV6Address()
class IPNetworkField(AutoTypedField):
AUTO_TYPE = IPNetwork()

View File

@@ -444,6 +444,16 @@ class TestInteger(TestField):
self.field.get_schema())
class TestNonNegativeInteger(TestField):
def setUp(self):
super(TestNonNegativeInteger, self).setUp()
self.field = fields.NonNegativeIntegerField()
self.coerce_good_values = [(1, 1), ('1', 1)]
self.coerce_bad_values = ['-2', '4.2', 'foo', None]
self.to_primitive_values = self.coerce_good_values[0:1]
self.from_primitive_values = self.coerce_good_values[0:1]
class TestFloat(TestField):
def setUp(self):
super(TestFloat, self).setUp()
@@ -461,6 +471,16 @@ class TestFloat(TestField):
self.field.get_schema())
class TestNonNegativeFloat(TestField):
def setUp(self):
super(TestNonNegativeFloat, self).setUp()
self.field = fields.NonNegativeFloatField()
self.coerce_good_values = [(1.1, 1.1), ('1.1', 1.1)]
self.coerce_bad_values = ['-4.2', 'foo', None]
self.to_primitive_values = self.coerce_good_values[0:1]
self.from_primitive_values = self.coerce_good_values[0:1]
class TestBoolean(TestField):
def setUp(self):
super(TestField, self).setUp()
@@ -739,6 +759,20 @@ class TestListOfSetsOfIntegers(TestField):
self.assertEqual('[set([1,2])]', self.field.stringify([set([1, 2])]))
class TestListOfIntegers(TestField):
def setUp(self):
super(TestListOfIntegers, self).setUp()
self.field = fields.ListOfIntegersField()
self.coerce_good_values = [(['1', 2], [1, 2]),
([1, 2], [1, 2])]
self.coerce_bad_values = [['foo']]
self.to_primitive_values = [([1], [1])]
self.from_primitive_values = [([1], [1])]
def test_stringify(self):
self.assertEqual('[[1, 2]]', self.field.stringify([[1, 2]]))
class TestLocalMethods(test.TestCase):
@mock.patch.object(obj_base.LOG, 'exception')
def test__make_class_properties_setter_value_error(self, mock_log):
@@ -971,6 +1005,28 @@ class TestIPAddressV6(TestField):
netaddr.IPAddress('::1'))]
class TestIPV4AndV6Address(TestField):
def setUp(self):
super(TestIPV4AndV6Address, self).setUp()
self.field = fields.IPV4AndV6Address()
self.coerce_good_values = [('::1', netaddr.IPAddress('::1')),
(netaddr.IPAddress('::1'),
netaddr.IPAddress('::1')),
('1.2.3.4',
netaddr.IPAddress('1.2.3.4')),
(netaddr.IPAddress('1.2.3.4'),
netaddr.IPAddress('1.2.3.4'))]
self.coerce_bad_values = ['1-2', 'foo']
self.to_primitive_values = [(netaddr.IPAddress('::1'),
'::1'),
(netaddr.IPAddress('1.2.3.4'),
'1.2.3.4')]
self.from_primitive_values = [('::1',
netaddr.IPAddress('::1')),
('1.2.3.4',
netaddr.IPAddress('1.2.3.4'))]
class TestIPNetwork(TestField):
def setUp(self):
super(TestIPNetwork, self).setUp()