Create some (incomplete) tests for the cornice adapter and fix it

This commit is contained in:
Christophe de Vienne 2013-03-28 23:30:06 +01:00
parent 6f9bb4d14f
commit c1f08c40db
5 changed files with 133 additions and 34 deletions

79
tests/test_cornice.py Normal file
View 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>'
)

View File

@ -1,6 +1,6 @@
# content of: tox.ini , put in same dir as setup.py
[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]
testtools=
@ -187,7 +187,18 @@ deps=
commands=
{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
[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]
basepython=python

14
tox.ini
View File

@ -1,5 +1,5 @@
[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]
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}/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]
basepython = python
deps =

View File

@ -61,7 +61,7 @@ def toxml(datatype, key, value):
else:
if wsme.types.isusertype(datatype):
return toxml(datatype.basetype,
key, datatype.tobasetype(value))
key, datatype.tobasetype(value))
elif wsme.types.iscomplex(datatype):
for attrdef in datatype._wsme_attributes:
attrvalue = getattr(value, attrdef.key)
@ -95,8 +95,7 @@ def fromxml(datatype, element):
if element.get('nil', False):
return None
if wsme.types.isusertype(datatype):
return datatype.frombasetype(
fromxml(datatype.basetype, element))
return datatype.frombasetype(fromxml(datatype.basetype, element))
if wsme.types.iscomplex(datatype):
obj = datatype()
for attrdef in datatype._wsme_attributes:
@ -243,7 +242,7 @@ def parse(s, datatypes, bodyarg):
tree = et.fromstring(s)
if bodyarg:
name = list(datatypes.keys())[0]
return fromxml(datatypes[name], tree)
return {name: fromxml(datatypes[name], tree)}
else:
kw = {}
extra_args = []

View File

@ -15,17 +15,13 @@ And use it::
return Message(text='Hello %s' % who)
"""
from __future__ import absolute_import
import json
import xml.etree.ElementTree as et
import wsme
import wsme.protocols
from wsme.protocols import restjson
from wsme.protocols import restxml
from wsme.rest import json as restjson
from wsme.rest import xml as restxml
import functools
from wsme.protocols.commons import (
from wsme.rest.args import (
args_from_params, args_from_body, combine_args
)
@ -37,11 +33,7 @@ class WSMEJsonRenderer(object):
def __call__(self, data, context):
response = context['request'].response
response.content_type = 'application/json'
data = restjson.tojson(
data['datatype'],
data['result']
)
return json.dumps(data)
return restjson.encode_result(data['result'], data['datatype'])
class WSMEXmlRenderer(object):
@ -51,34 +43,40 @@ class WSMEXmlRenderer(object):
def __call__(self, data, context):
response = context['request'].response
response.content_type = 'text/xml'
data = restxml.toxml(
data['datatype'],
'result',
data['result']
)
return et.tostring(data)
return restxml.encode_result(data['result'], data['datatype'])
def get_outputformat(request):
df = None
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):
sig = wsme.sig(*args, **kwargs)
sig = wsme.signature(*args, **kwargs)
def decorate(f):
sig(f)
funcdef = wsme.api.FunctionDefinition.get(f)
funcdef.resolve_types(wsme.types.registry)
@functools.wraps(f)
def callfunction(request):
args, kwargs = combine_args(
funcdef,
args_from_params(funcdef, request.params),
args_from_body(funcdef, request.body, request.content_type)
(args_from_params(funcdef, request.params),
args_from_body(funcdef, request.body, request.content_type))
)
if 'application/json' in request.headers['Accept']:
request.override_renderer = 'wsmejson'
elif 'text/xml' in request.headers['Accept']:
request.override_renderer = 'wsmexml'
else:
request.override_renderer = 'wsmejson'
request.override_renderer = 'wsme' + get_outputformat(request)
return {
'datatype': funcdef.return_type,
'result': f(*args, **kwargs)