Add support for one-of with any type

This commit is contained in:
Daniel Bradburn 2019-03-02 21:44:01 +01:00
parent 4d99cbe7e1
commit 7d903a8907
3 changed files with 57 additions and 9 deletions

View file

@ -219,6 +219,9 @@ class Schema(object):
else:
raise InvalidSchemaValue(msg, value, self.format)
else:
if self.enum and value not in self.enum:
raise InvalidSchemaValue(
"Value {value} not in enum choices: {type}", value, self.enum)
formatstring = self.STRING_FORMAT_CALLABLE_GETTER[schema_format]
try:
@ -251,13 +254,30 @@ class Schema(object):
SchemaType.INTEGER, SchemaType.NUMBER, SchemaType.STRING,
]
cast_mapping = self.get_cast_mapping()
for schema_type in types_resolve_order:
cast_callable = cast_mapping[schema_type]
try:
return cast_callable(value)
# @todo: remove ValueError when validation separated
except (OpenAPISchemaError, TypeError, ValueError):
continue
if self.one_of:
result = None
for subschema in self.one_of:
try:
casted = subschema.cast(value, custom_formatters)
except (OpenAPISchemaError, TypeError, ValueError):
continue
else:
if result is not None:
raise MultipleOneOfSchema(self.type)
result = casted
if result is None:
raise NoOneOfSchema(self.type)
return result
else:
for schema_type in types_resolve_order:
cast_callable = cast_mapping[schema_type]
try:
return cast_callable(value)
# @todo: remove ValueError when validation separated
except (OpenAPISchemaError, TypeError, ValueError):
continue
raise NoValidSchema(value)

View file

@ -1,5 +1,6 @@
import json
import pytest
from datetime import datetime
from base64 import b64encode
from uuid import UUID
from six import iteritems, text_type
@ -1213,7 +1214,7 @@ class TestPetstore(object):
assert parameters == {}
assert isinstance(body, BaseModel)
assert body.created == created
assert body.created == datetime(2016, 4, 16, 16, 6, 5)
assert body.name == pet_name
code = 400
@ -1257,7 +1258,7 @@ class TestPetstore(object):
)
parameters = request.get_parameters(spec)
with pytest.raises(NoValidSchema):
with pytest.raises(InvalidMediaTypeValue):
request.get_body(spec)
assert parameters == {}

View file

@ -269,6 +269,33 @@ class TestSchemaUnmarshal(object):
with pytest.raises(InvalidSchemaValue):
schema.unmarshal(value)
def test_schema_any_one_of(self):
schema = Schema(one_of=[
Schema('string'),
Schema('array', items=Schema('string')),
])
assert schema.unmarshal(['hello']) == ['hello']
def test_schema_any_one_of_mutiple(self):
schema = Schema(one_of=[
Schema('array', items=Schema('string')),
Schema('array', items=Schema('number')),
])
with pytest.raises(MultipleOneOfSchema):
schema.unmarshal([])
def test_schema_any_one_of_no_valid(self):
schema = Schema(one_of=[
Schema('array', items=Schema('string')),
Schema('array', items=Schema('number')),
])
with pytest.raises(NoOneOfSchema):
schema.unmarshal({})
def test_schema_any(self):
schema = Schema()
assert schema.unmarshal('string') == 'string'
class TestSchemaValidate(object):