Create some (incomplete) tests for the cornice adapter and fix it
This commit is contained in:
parent
6f9bb4d14f
commit
c1f08c40db
79
tests/test_cornice.py
Normal file
79
tests/test_cornice.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import unittest
|
||||||
|
import json
|
||||||
|
|
||||||
|
import webtest
|
||||||
|
|
||||||
|
from cornice import Service
|
||||||
|
from pyramid.config import Configurator
|
||||||
|
|
||||||
|
from wsme.types import text, Base
|
||||||
|
from wsmeext.cornice import signature
|
||||||
|
|
||||||
|
|
||||||
|
class User(Base):
|
||||||
|
id = int
|
||||||
|
name = text
|
||||||
|
|
||||||
|
users = Service(name='users', path='/users')
|
||||||
|
|
||||||
|
|
||||||
|
@users.get()
|
||||||
|
@signature([User])
|
||||||
|
def users_get():
|
||||||
|
return [User(id=1, name='first')]
|
||||||
|
|
||||||
|
|
||||||
|
@users.post()
|
||||||
|
@signature(User, body=User)
|
||||||
|
def users_create(data):
|
||||||
|
data.id = 2
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def make_app():
|
||||||
|
config = Configurator()
|
||||||
|
config.include("cornice")
|
||||||
|
config.include("wsmeext.cornice")
|
||||||
|
config.scan("test_cornice")
|
||||||
|
return config.make_wsgi_app()
|
||||||
|
|
||||||
|
|
||||||
|
class WSMECorniceTestCase(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.app = webtest.TestApp(make_app())
|
||||||
|
|
||||||
|
def test_get_json_list(self):
|
||||||
|
resp = self.app.get('/users')
|
||||||
|
self.assertEquals(
|
||||||
|
resp.body,
|
||||||
|
'[{"id": 1, "name": "first"}]'
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_get_xml_list(self):
|
||||||
|
resp = self.app.get('/users', headers={"Accept": "text/xml"})
|
||||||
|
self.assertEquals(
|
||||||
|
resp.body,
|
||||||
|
'<result><item><id>1</id><name>first</name></item></result>'
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_post_json_data(self):
|
||||||
|
data = json.dumps({"name": "new"})
|
||||||
|
resp = self.app.post(
|
||||||
|
'/users', data,
|
||||||
|
headers={"Content-Type": "application/json"}
|
||||||
|
)
|
||||||
|
self.assertEquals(
|
||||||
|
resp.body,
|
||||||
|
'{"id": 2, "name": "new"}'
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_post_xml_data(self):
|
||||||
|
data = '<data><name>new</name></data>'
|
||||||
|
resp = self.app.post(
|
||||||
|
'/users', data,
|
||||||
|
headers={"Content-Type": "text/xml"}
|
||||||
|
)
|
||||||
|
self.assertEquals(
|
||||||
|
resp.body,
|
||||||
|
'<result><id>2</id><name>new</name></result>'
|
||||||
|
)
|
15
tox-tmpl.ini
15
tox-tmpl.ini
@ -1,6 +1,6 @@
|
|||||||
# content of: tox.ini , put in same dir as setup.py
|
# content of: tox.ini , put in same dir as setup.py
|
||||||
[tox]
|
[tox]
|
||||||
envlist = py27,py27-nolxml,py32,py32-nolxml,pypy,py25-simplejson,sphinxext,tg11,tg15,pecan,flask,coverage
|
envlist = py27,py27-nolxml,py32,py32-nolxml,pypy,py25-simplejson,sphinxext,tg11,tg15,pecan,flask,cornice,coverage
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
testtools=
|
testtools=
|
||||||
@ -187,7 +187,18 @@ deps=
|
|||||||
commands=
|
commands=
|
||||||
{envbindir}/nosetests tests/test_flask.py --with-xunit --xunit-file nosetests-{envname}.xml --verbose --with-coverage --cover-package wsme {posargs}
|
{envbindir}/nosetests tests/test_flask.py --with-xunit --xunit-file nosetests-{envname}.xml --verbose --with-coverage --cover-package wsme {posargs}
|
||||||
{envbindir}/coverage xml -o coverage-{envname}.xml wsme/*.py wsmeext/flask.py
|
{envbindir}/coverage xml -o coverage-{envname}.xml wsme/*.py wsmeext/flask.py
|
||||||
|
|
||||||
|
[testenv:cornice]
|
||||||
|
basepython=python2.7
|
||||||
|
deps=
|
||||||
|
d2to1
|
||||||
|
nose
|
||||||
|
webtest
|
||||||
|
coverage
|
||||||
|
cornice
|
||||||
|
commands=
|
||||||
|
{envbindir}/nosetests tests/test_cornice.py --with-xunit --xunit-file nosetests-{envname}.xml --verbose --with-coverage --cover-package wsmeext {posargs}
|
||||||
|
{envbindir}/coverage xml -o coverage-{envname}.xml wsme/*.py wsmeext/cornice.py
|
||||||
|
|
||||||
[testenv:coverage]
|
[testenv:coverage]
|
||||||
basepython=python
|
basepython=python
|
||||||
|
14
tox.ini
14
tox.ini
@ -1,5 +1,5 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py27,py27-nolxml,py32,py32-nolxml,pypy,py25-simplejson,sphinxext,tg11,tg15,pecan,flask,coverage
|
envlist = py27,py27-nolxml,py32,py32-nolxml,pypy,py25-simplejson,sphinxext,tg11,tg15,pecan,flask,cornice,coverage
|
||||||
|
|
||||||
[common]
|
[common]
|
||||||
testtools =
|
testtools =
|
||||||
@ -105,6 +105,18 @@ commands =
|
|||||||
{envbindir}/nosetests tests/test_flask.py --with-xunit --xunit-file nosetests-{envname}.xml --verbose --with-coverage --cover-package wsme {posargs}
|
{envbindir}/nosetests tests/test_flask.py --with-xunit --xunit-file nosetests-{envname}.xml --verbose --with-coverage --cover-package wsme {posargs}
|
||||||
{envbindir}/coverage xml -o coverage-{envname}.xml wsme/*.py wsmeext/flask.py
|
{envbindir}/coverage xml -o coverage-{envname}.xml wsme/*.py wsmeext/flask.py
|
||||||
|
|
||||||
|
[testenv:cornice]
|
||||||
|
basepython = python2.7
|
||||||
|
deps =
|
||||||
|
d2to1
|
||||||
|
nose
|
||||||
|
webtest
|
||||||
|
coverage
|
||||||
|
cornice
|
||||||
|
commands =
|
||||||
|
{envbindir}/nosetests tests/test_cornice.py --with-xunit --xunit-file nosetests-{envname}.xml --verbose --with-coverage --cover-package wsmeext {posargs}
|
||||||
|
{envbindir}/coverage xml -o coverage-{envname}.xml wsme/*.py wsmeext/cornice.py
|
||||||
|
|
||||||
[testenv:coverage]
|
[testenv:coverage]
|
||||||
basepython = python
|
basepython = python
|
||||||
deps =
|
deps =
|
||||||
|
@ -61,7 +61,7 @@ def toxml(datatype, key, value):
|
|||||||
else:
|
else:
|
||||||
if wsme.types.isusertype(datatype):
|
if wsme.types.isusertype(datatype):
|
||||||
return toxml(datatype.basetype,
|
return toxml(datatype.basetype,
|
||||||
key, datatype.tobasetype(value))
|
key, datatype.tobasetype(value))
|
||||||
elif wsme.types.iscomplex(datatype):
|
elif wsme.types.iscomplex(datatype):
|
||||||
for attrdef in datatype._wsme_attributes:
|
for attrdef in datatype._wsme_attributes:
|
||||||
attrvalue = getattr(value, attrdef.key)
|
attrvalue = getattr(value, attrdef.key)
|
||||||
@ -95,8 +95,7 @@ def fromxml(datatype, element):
|
|||||||
if element.get('nil', False):
|
if element.get('nil', False):
|
||||||
return None
|
return None
|
||||||
if wsme.types.isusertype(datatype):
|
if wsme.types.isusertype(datatype):
|
||||||
return datatype.frombasetype(
|
return datatype.frombasetype(fromxml(datatype.basetype, element))
|
||||||
fromxml(datatype.basetype, element))
|
|
||||||
if wsme.types.iscomplex(datatype):
|
if wsme.types.iscomplex(datatype):
|
||||||
obj = datatype()
|
obj = datatype()
|
||||||
for attrdef in datatype._wsme_attributes:
|
for attrdef in datatype._wsme_attributes:
|
||||||
@ -243,7 +242,7 @@ def parse(s, datatypes, bodyarg):
|
|||||||
tree = et.fromstring(s)
|
tree = et.fromstring(s)
|
||||||
if bodyarg:
|
if bodyarg:
|
||||||
name = list(datatypes.keys())[0]
|
name = list(datatypes.keys())[0]
|
||||||
return fromxml(datatypes[name], tree)
|
return {name: fromxml(datatypes[name], tree)}
|
||||||
else:
|
else:
|
||||||
kw = {}
|
kw = {}
|
||||||
extra_args = []
|
extra_args = []
|
||||||
|
@ -15,17 +15,13 @@ And use it::
|
|||||||
return Message(text='Hello %s' % who)
|
return Message(text='Hello %s' % who)
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
import json
|
|
||||||
|
|
||||||
import xml.etree.ElementTree as et
|
|
||||||
|
|
||||||
import wsme
|
import wsme
|
||||||
import wsme.protocols
|
from wsme.rest import json as restjson
|
||||||
from wsme.protocols import restjson
|
from wsme.rest import xml as restxml
|
||||||
from wsme.protocols import restxml
|
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
from wsme.protocols.commons import (
|
from wsme.rest.args import (
|
||||||
args_from_params, args_from_body, combine_args
|
args_from_params, args_from_body, combine_args
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -37,11 +33,7 @@ class WSMEJsonRenderer(object):
|
|||||||
def __call__(self, data, context):
|
def __call__(self, data, context):
|
||||||
response = context['request'].response
|
response = context['request'].response
|
||||||
response.content_type = 'application/json'
|
response.content_type = 'application/json'
|
||||||
data = restjson.tojson(
|
return restjson.encode_result(data['result'], data['datatype'])
|
||||||
data['datatype'],
|
|
||||||
data['result']
|
|
||||||
)
|
|
||||||
return json.dumps(data)
|
|
||||||
|
|
||||||
|
|
||||||
class WSMEXmlRenderer(object):
|
class WSMEXmlRenderer(object):
|
||||||
@ -51,34 +43,40 @@ class WSMEXmlRenderer(object):
|
|||||||
def __call__(self, data, context):
|
def __call__(self, data, context):
|
||||||
response = context['request'].response
|
response = context['request'].response
|
||||||
response.content_type = 'text/xml'
|
response.content_type = 'text/xml'
|
||||||
data = restxml.toxml(
|
return restxml.encode_result(data['result'], data['datatype'])
|
||||||
data['datatype'],
|
|
||||||
'result',
|
|
||||||
data['result']
|
def get_outputformat(request):
|
||||||
)
|
df = None
|
||||||
return et.tostring(data)
|
if 'Accept' in request.headers:
|
||||||
|
if 'application/json' in request.headers['Accept']:
|
||||||
|
df = 'json'
|
||||||
|
elif 'text/xml' in request.headers['Accept']:
|
||||||
|
df = 'xml'
|
||||||
|
if df is None and 'Content-Type' in request.headers:
|
||||||
|
if 'application/json' in request.headers['Content-Type']:
|
||||||
|
df = 'json'
|
||||||
|
elif 'text/xml' in request.headers['Content-Type']:
|
||||||
|
df = 'xml'
|
||||||
|
return df if df else 'json'
|
||||||
|
|
||||||
|
|
||||||
def signature(*args, **kwargs):
|
def signature(*args, **kwargs):
|
||||||
sig = wsme.sig(*args, **kwargs)
|
sig = wsme.signature(*args, **kwargs)
|
||||||
|
|
||||||
def decorate(f):
|
def decorate(f):
|
||||||
sig(f)
|
sig(f)
|
||||||
funcdef = wsme.api.FunctionDefinition.get(f)
|
funcdef = wsme.api.FunctionDefinition.get(f)
|
||||||
|
funcdef.resolve_types(wsme.types.registry)
|
||||||
|
|
||||||
@functools.wraps(f)
|
@functools.wraps(f)
|
||||||
def callfunction(request):
|
def callfunction(request):
|
||||||
args, kwargs = combine_args(
|
args, kwargs = combine_args(
|
||||||
funcdef,
|
funcdef,
|
||||||
args_from_params(funcdef, request.params),
|
(args_from_params(funcdef, request.params),
|
||||||
args_from_body(funcdef, request.body, request.content_type)
|
args_from_body(funcdef, request.body, request.content_type))
|
||||||
)
|
)
|
||||||
if 'application/json' in request.headers['Accept']:
|
request.override_renderer = 'wsme' + get_outputformat(request)
|
||||||
request.override_renderer = 'wsmejson'
|
|
||||||
elif 'text/xml' in request.headers['Accept']:
|
|
||||||
request.override_renderer = 'wsmexml'
|
|
||||||
else:
|
|
||||||
request.override_renderer = 'wsmejson'
|
|
||||||
return {
|
return {
|
||||||
'datatype': funcdef.return_type,
|
'datatype': funcdef.return_type,
|
||||||
'result': f(*args, **kwargs)
|
'result': f(*args, **kwargs)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user