SQLAlchemy now optional, better jsonify test coverage

This commit is contained in:
Mark McClain
2011-01-17 12:37:22 -05:00
parent ed5c644779
commit 5181fd7edc
2 changed files with 60 additions and 9 deletions

View File

@@ -5,10 +5,16 @@ except ImportError:
from datetime import datetime, date
from decimal import Decimal
from webob.multidict import MultiDict
from sqlalchemy.engine.base import ResultProxy, RowProxy
from webob.multidict import MultiDict, UnicodeMultiDict
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
#
@@ -32,6 +38,9 @@ class GenericJSON(JSONEncoder):
elif isinstance(obj, (date, datetime)):
return str(obj)
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)
elif is_saobject(obj):
props = {}
@@ -43,7 +52,7 @@ class GenericJSON(JSONEncoder):
return dict(rows=list(obj), count=obj.rowcount)
elif isinstance(obj, RowProxy):
return dict(rows=dict(obj), count=1)
elif isinstance(obj, MultiDict):
elif isinstance(obj, (MultiDict, UnicodeMultiDict)):
return obj.mixed()
else:
return JSONEncoder.default(self, obj)
@@ -63,6 +72,4 @@ _instance = GenericFunctionJSON()
def encode(obj):
if isinstance(obj, basestring):
return _instance.encode(obj)
return _instance.encode(obj)

View File

@@ -1,8 +1,12 @@
from pecan.jsonify import jsonify, encode
from pecan import Pecan, expose
from webtest import TestApp
from json import loads
from datetime import datetime, date
from decimal import Decimal
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():
class Person(object):
@@ -59,3 +63,43 @@ class TestJsonify(object):
r = app.get('/')
assert r.status_int == 200
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())