Merge pull request #133 from crunchr/support-any-type-with-one-of-rb1

Add support for one-of with any type
This commit is contained in:
A 2019-06-17 13:28:41 +01:00 committed by GitHub
commit 0df1d051b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 11 deletions

View file

@ -2,7 +2,6 @@
import attr import attr
import functools import functools
import logging import logging
from base64 import b64decode, b64encode
from collections import defaultdict from collections import defaultdict
from datetime import date, datetime from datetime import date, datetime
from uuid import UUID from uuid import UUID
@ -229,6 +228,9 @@ class Schema(object):
else: else:
raise InvalidSchemaValue(msg, value, self.format) raise InvalidSchemaValue(msg, value, self.format)
else: 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] formatstring = self.STRING_FORMAT_CALLABLE_GETTER[schema_format]
try: try:
@ -278,13 +280,30 @@ class Schema(object):
SchemaType.INTEGER, SchemaType.NUMBER, SchemaType.STRING, SchemaType.INTEGER, SchemaType.NUMBER, SchemaType.STRING,
] ]
cast_mapping = self.get_cast_mapping() cast_mapping = self.get_cast_mapping()
for schema_type in types_resolve_order: if self.one_of:
cast_callable = cast_mapping[schema_type] result = None
try: for subschema in self.one_of:
return cast_callable(value) try:
# @todo: remove ValueError when validation separated casted = subschema.cast(value, custom_formatters)
except (OpenAPISchemaError, TypeError, ValueError): except (OpenAPISchemaError, TypeError, ValueError):
continue 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) raise NoValidSchema(value)

View file

@ -1,5 +1,6 @@
import json import json
import pytest import pytest
from datetime import datetime
from base64 import b64encode from base64 import b64encode
from uuid import UUID from uuid import UUID
from six import iteritems, text_type from six import iteritems, text_type
@ -19,7 +20,7 @@ from openapi_core.schema.request_bodies.models import RequestBody
from openapi_core.schema.responses.models import Response from openapi_core.schema.responses.models import Response
from openapi_core.schema.schemas.enums import SchemaType from openapi_core.schema.schemas.enums import SchemaType
from openapi_core.schema.schemas.exceptions import ( from openapi_core.schema.schemas.exceptions import (
NoValidSchema, InvalidSchemaProperty, InvalidSchemaValue, InvalidSchemaProperty, InvalidSchemaValue,
) )
from openapi_core.schema.schemas.models import Schema from openapi_core.schema.schemas.models import Schema
from openapi_core.schema.servers.exceptions import InvalidServer from openapi_core.schema.servers.exceptions import InvalidServer
@ -1213,7 +1214,7 @@ class TestPetstore(object):
assert parameters == {} assert parameters == {}
assert isinstance(body, BaseModel) assert isinstance(body, BaseModel)
assert body.created == created assert body.created == datetime(2016, 4, 16, 16, 6, 5)
assert body.name == pet_name assert body.name == pet_name
code = 400 code = 400
@ -1257,7 +1258,7 @@ class TestPetstore(object):
) )
parameters = request.get_parameters(spec) parameters = request.get_parameters(spec)
with pytest.raises(NoValidSchema): with pytest.raises(InvalidMediaTypeValue):
request.get_body(spec) request.get_body(spec)
assert parameters == {} assert parameters == {}

View file

@ -300,6 +300,33 @@ class TestSchemaUnmarshal(object):
assert result == 1.2 assert result == 1.2
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): class TestSchemaValidate(object):