Commit 264e786d authored by Ellery Newcomer's avatar Ellery Newcomer
Browse files

add support for items and uniqueItems

to yaml parameters. Also, improve validity of things coming out of yaml
parser.
parent 100cbc65
......@@ -75,14 +75,19 @@ For the fields allowed in each parameter, see the
fields and the
`Data Type Fields <https://github.com/swagger-api/swagger-spec/blob/master/versions/1.2.md#433-data-type-fields>`_.
Exceptions: `$ref`, `items`, and `uniqueItems` are not currently supported.
Exceptions: `$ref` is not currently supported.
parameters meta-fields
----------------------
pytype
~~~~~~
Specify a serializer you want to use to populate :code:`type`.
If you have a Django Rest Framework serializer that you would like to use
to populate :code:`type` you can specify it with :code:`pytype`:
.. code-block:: yaml
pytype: .serializers.FooSerializer
Overriding parameters
--------------------
......
......@@ -971,6 +971,25 @@ class YAMLDocstringParser(object):
view_mocker = self._load_class(view_mocker, callback)
return view_mocker
def normalize_data_format(self, data_type, data_format):
if data_type == 'array':
return None
flatten_primitives = [
val for sublist in BaseMethodIntrospector.PRIMITIVES.values()
for val in sublist
]
if data_format not in flatten_primitives:
formats = BaseMethodIntrospector.PRIMITIVES.get(data_type, None)
if formats:
data_format = formats[0]
else:
data_format = None
if data_format == data_type:
data_format = None
return data_format
def get_parameters(self, callback):
"""
Retrieves parameters from YAML object
......@@ -1001,33 +1020,43 @@ class YAMLDocstringParser(object):
# Data Format
data_format = field.get('format', None)
flatten_primitives = [
val for sublist in BaseMethodIntrospector.PRIMITIVES.values()
for val in sublist
]
if data_format not in flatten_primitives:
formats = BaseMethodIntrospector.PRIMITIVES.get(data_type, None)
if formats:
data_format = formats[0]
else:
data_format = 'string'
data_format = self.normalize_data_format(data_type, data_format)
f = {
'paramType': param_type,
'name': field.get('name', None),
'description': field.get('description', None),
'description': field.get('description', ''),
'type': data_type,
'format': data_format,
'required': field.get('required', False),
'defaultValue': field.get('defaultValue', None),
}
if field.get('defaultValue', None) is not None:
f['defaultValue'] = field.get('defaultValue', None)
if data_format is not None:
f['format'] = data_format
# Allow Multiple Values &f=1,2,3,4
if field.get('allowMultiple'):
f['allowMultiple'] = True
if data_type == 'array':
items = field.get('items', {})
elt_data_type = items.get('type', 'string')
elt_data_format = items.get('type', 'format')
elt_data_format = self.normalize_data_format(elt_data_type, elt_data_format)
f['items'] = {
'type': elt_data_type,
}
if elt_data_format is not None:
f['items']['format'] = elt_data_format
uniqueItems = field.get('uniqueItems', None)
if uniqueItems is not None:
f['uniqueItems'] = uniqueItems
# Min/Max are optional
if 'minimum' in field and data_type == 'integer':
f['minimum'] = str(field.get('minimum', 0))
......
......@@ -2579,3 +2579,109 @@ if platform.python_version_tuple()[:2] != ('3', '2'):
json = parse_json(response)
self.assertIn("KitchenSinkSerializer", json['models'])
validator.validate(json)
def test_yaml_parameters(self):
class MockApiView(APIView):
"""
---
GET:
parameters:
- name: bob
type: string
enum:
- taco
- enchilada
- name: rob
type: string
defaultValue: 'lewis'
- name: i1
type: integer
format: int32
- name: i2
type: integer
format: int64
- name: idurp
type: integer
format: smokey
minimum: 1
maximum: 100
- name: mandy
type: string
allowMultiple: true
uniqueItems: true
- name: sandy
type: array
items:
type: integer
- name: candy
type: array
items:
type: integer
uniqueItems: true
"""
def get(self, request):
pass
self.url_patterns = patterns(
'',
url(r'^a-view/?$', MockApiView.as_view(), name='a test view'),
url(r'^swagger/', include('rest_framework_swagger.urls')),
)
urls = import_module(settings.ROOT_URLCONF)
urls.urlpatterns = self.url_patterns
validator = self.get_validator("resourceListing")
response = self.client.get("/swagger/api-docs/")
json = parse_json(response)
validator.validate(json)
validator = self.get_validator("apiDeclaration")
response = self.client.get("/swagger/api-docs/a-view")
json = parse_json(response)
validator.validate(json)
self.assertEqual('object', json['apis'][0]['operations'][0]['type'])
parameters = json['apis'][0]['operations'][0]['parameters']
self.assertNotIn('format', parameters[0])
self.assertNotIn('defaultValue', parameters[0])
self.assertNotIn('format', parameters[1])
self.assertEqual('lewis', parameters[1]['defaultValue'])
self.assertEqual('', parameters[1]['description'])
self.assertEqual('i1', parameters[2]['name'])
self.assertEqual('int32', parameters[2]['format'])
self.assertEqual('i2', parameters[3]['name'])
self.assertEqual('int64', parameters[3]['format'])
self.assertEqual('idurp', parameters[4]['name'])
self.assertEqual('int32', parameters[4]['format'])
self.assertEqual('sandy', parameters[6]['name'])
self.assertEqual('integer', parameters[6]['items']['type'])
self.assertEqual('int32', parameters[6]['items']['format'])
self.assertEqual('candy', parameters[7]['name'])
self.assertIn('uniqueItems', parameters[7])
def test_raw_array(self):
class MockApiView(APIView):
"""
---
GET:
parameters:
- name: bob
type: array
items:
type: string
"""
def get(self, request):
pass
self.url_patterns = patterns(
'',
url(r'^a-view/?$', MockApiView.as_view(), name='a test view'),
url(r'^swagger/', include('rest_framework_swagger.urls')),
)
urls = import_module(settings.ROOT_URLCONF)
urls.urlpatterns = self.url_patterns
validator = self.get_validator("resourceListing")
response = self.client.get("/swagger/api-docs/")
json = parse_json(response)
validator.validate(json)
validator = self.get_validator("apiDeclaration")
response = self.client.get("/swagger/api-docs/a-view")
json = parse_json(response)
validator.validate(json)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment