Flesh out ListProperty, add StringProperty
parent
253989cc52
commit
474833248d
|
@ -1,5 +1,6 @@
|
||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
class Property(object):
|
class Property(object):
|
||||||
|
@ -72,21 +73,66 @@ class Property(object):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class List(Property):
|
class ListProperty(Property):
|
||||||
|
|
||||||
def __init__(self, contained):
|
def __init__(self, contained):
|
||||||
"""
|
"""
|
||||||
contained should be a type whose constructor creates an object from the value
|
contained should be a type whose constructor creates an object from the value
|
||||||
"""
|
"""
|
||||||
self.contained = contained
|
if contained == StringProperty:
|
||||||
|
self.contained = StringProperty().string_type
|
||||||
|
elif contained == BooleanProperty:
|
||||||
|
self.contained = bool
|
||||||
|
else:
|
||||||
|
self.contained = contained
|
||||||
|
|
||||||
def validate(self, value):
|
def validate(self, value):
|
||||||
# TODO: ensure iterable
|
try:
|
||||||
for item in value:
|
list_ = self.clean(value)
|
||||||
self.contained.validate(item)
|
except ValueError:
|
||||||
|
raise
|
||||||
|
|
||||||
|
if len(list_) < 1:
|
||||||
|
raise ValueError("must not be empty.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
for item in list_:
|
||||||
|
self.contained.validate(item)
|
||||||
|
except ValueError:
|
||||||
|
raise
|
||||||
|
except AttributeError:
|
||||||
|
# type of list has no validate() function (eg. built in Python types)
|
||||||
|
# TODO Should we raise an error here?
|
||||||
|
pass
|
||||||
|
|
||||||
|
return list_
|
||||||
|
|
||||||
def clean(self, value):
|
def clean(self, value):
|
||||||
return [self.contained(x) for x in value]
|
return [self.contained(x) for x in value]
|
||||||
|
try:
|
||||||
|
return [self.contained(x) for x in value]
|
||||||
|
except TypeError:
|
||||||
|
raise ValueError("must be an iterable over a type whose constructor creates an object from the value.")
|
||||||
|
|
||||||
|
|
||||||
|
class StringProperty(Property):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
if sys.version_info[0] == 2:
|
||||||
|
self.string_type = unicode
|
||||||
|
else:
|
||||||
|
self.string_type = str
|
||||||
|
super(StringProperty, self).__init__()
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
return self.string_type(value)
|
||||||
|
|
||||||
|
def validate(self, value):
|
||||||
|
try:
|
||||||
|
val = self.clean(value)
|
||||||
|
except ValueError:
|
||||||
|
raise
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
class TypeProperty(Property):
|
class TypeProperty(Property):
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from stix2.properties import (Property, BooleanProperty, IDProperty,
|
from stix2.properties import (Property, BooleanProperty, ListProperty,
|
||||||
ReferenceProperty, TypeProperty)
|
StringProperty, TypeProperty, IDProperty,
|
||||||
|
ReferenceProperty)
|
||||||
|
|
||||||
|
|
||||||
def test_property():
|
def test_property():
|
||||||
|
@ -50,6 +51,22 @@ def test_fixed_property():
|
||||||
assert p.validate(p.default())
|
assert p.validate(p.default())
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_property():
|
||||||
|
p = ListProperty(StringProperty)
|
||||||
|
|
||||||
|
assert p.validate(['abc', 'xyz'])
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
p.validate([])
|
||||||
|
|
||||||
|
|
||||||
|
def test_string_property():
|
||||||
|
prop = StringProperty()
|
||||||
|
|
||||||
|
assert prop.validate('foobar')
|
||||||
|
assert prop.validate(1)
|
||||||
|
assert prop.validate([1, 2, 3])
|
||||||
|
|
||||||
|
|
||||||
def test_type_property():
|
def test_type_property():
|
||||||
prop = TypeProperty('my-type')
|
prop = TypeProperty('my-type')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue