SQLAlchemy now optional, better jsonify test coverage
This commit is contained in:
@@ -5,10 +5,16 @@ except ImportError:
|
|||||||
|
|
||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from webob.multidict import MultiDict
|
from webob.multidict import MultiDict, UnicodeMultiDict
|
||||||
from sqlalchemy.engine.base import ResultProxy, RowProxy
|
|
||||||
from simplegeneric import generic
|
from simplegeneric import generic
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sqlalchemy.engine.base import ResultProxy, RowProxy
|
||||||
|
except ImportError: #pragma no cover
|
||||||
|
# dummy classes since we don't have SQLAlchemy installed
|
||||||
|
class ResultProxy: pass
|
||||||
|
class RowProxy: pass
|
||||||
|
|
||||||
#
|
#
|
||||||
# exceptions
|
# exceptions
|
||||||
#
|
#
|
||||||
@@ -32,6 +38,9 @@ class GenericJSON(JSONEncoder):
|
|||||||
elif isinstance(obj, (date, datetime)):
|
elif isinstance(obj, (date, datetime)):
|
||||||
return str(obj)
|
return str(obj)
|
||||||
elif isinstance(obj, Decimal):
|
elif isinstance(obj, Decimal):
|
||||||
|
# XXX What to do about JSONEncoder crappy handling of Decimals?
|
||||||
|
# SimpleJSON has better Decimal encoding than the std lib
|
||||||
|
# but only in recent versions
|
||||||
return float(obj)
|
return float(obj)
|
||||||
elif is_saobject(obj):
|
elif is_saobject(obj):
|
||||||
props = {}
|
props = {}
|
||||||
@@ -43,7 +52,7 @@ class GenericJSON(JSONEncoder):
|
|||||||
return dict(rows=list(obj), count=obj.rowcount)
|
return dict(rows=list(obj), count=obj.rowcount)
|
||||||
elif isinstance(obj, RowProxy):
|
elif isinstance(obj, RowProxy):
|
||||||
return dict(rows=dict(obj), count=1)
|
return dict(rows=dict(obj), count=1)
|
||||||
elif isinstance(obj, MultiDict):
|
elif isinstance(obj, (MultiDict, UnicodeMultiDict)):
|
||||||
return obj.mixed()
|
return obj.mixed()
|
||||||
else:
|
else:
|
||||||
return JSONEncoder.default(self, obj)
|
return JSONEncoder.default(self, obj)
|
||||||
@@ -63,6 +72,4 @@ _instance = GenericFunctionJSON()
|
|||||||
|
|
||||||
|
|
||||||
def encode(obj):
|
def encode(obj):
|
||||||
if isinstance(obj, basestring):
|
|
||||||
return _instance.encode(obj)
|
|
||||||
return _instance.encode(obj)
|
return _instance.encode(obj)
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
from pecan.jsonify import jsonify, encode
|
from datetime import datetime, date
|
||||||
from pecan import Pecan, expose
|
from decimal import Decimal
|
||||||
from webtest import TestApp
|
|
||||||
from json import loads
|
from json import loads
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from pecan.jsonify import jsonify, encode
|
||||||
|
from pecan import Pecan, expose, request
|
||||||
|
from webtest import TestApp
|
||||||
|
from webob.multidict import MultiDict, UnicodeMultiDict
|
||||||
|
|
||||||
def make_person():
|
def make_person():
|
||||||
class Person(object):
|
class Person(object):
|
||||||
@@ -59,3 +63,43 @@ class TestJsonify(object):
|
|||||||
r = app.get('/')
|
r = app.get('/')
|
||||||
assert r.status_int == 200
|
assert r.status_int == 200
|
||||||
assert loads(r.body) == {'name':'Jonathan LaCour'}
|
assert loads(r.body) == {'name':'Jonathan LaCour'}
|
||||||
|
|
||||||
|
class TestJsonifyGenericEncoder(TestCase):
|
||||||
|
def test_json_callable(self):
|
||||||
|
class JsonCallable(object):
|
||||||
|
def __init__(self, arg):
|
||||||
|
self.arg = arg
|
||||||
|
def __json__(self):
|
||||||
|
return {"arg":self.arg}
|
||||||
|
|
||||||
|
result = encode(JsonCallable('foo'))
|
||||||
|
assert loads(result) == {'arg':'foo'}
|
||||||
|
|
||||||
|
def test_datetime(self):
|
||||||
|
today = date.today()
|
||||||
|
now = datetime.now()
|
||||||
|
|
||||||
|
result = encode(today)
|
||||||
|
assert loads(result) == str(today)
|
||||||
|
|
||||||
|
result = encode(now)
|
||||||
|
assert loads(result) == str(now)
|
||||||
|
|
||||||
|
def test_decimal(self):
|
||||||
|
# XXX Testing for float match which is inexact
|
||||||
|
|
||||||
|
d = Decimal('1.1')
|
||||||
|
result = encode(d)
|
||||||
|
assert loads(result) == float(d)
|
||||||
|
|
||||||
|
def test_multidict(self):
|
||||||
|
md = MultiDict()
|
||||||
|
md.add('arg', 'foo')
|
||||||
|
md.add('arg', 'bar')
|
||||||
|
result = encode(md)
|
||||||
|
assert loads(result) == {'arg': ['foo', 'bar']}
|
||||||
|
|
||||||
|
def test_fallback_to_builtin_encoder(self):
|
||||||
|
class Foo(object): pass
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, encode, Foo())
|
||||||
|
|||||||
Reference in New Issue
Block a user