Files
pecan/pecan/tests/test_base.py
2012-03-07 12:04:40 -05:00

1105 lines
35 KiB
Python

from formencode import Schema, validators
from paste.recursive import ForwardRequestException
from paste.translogger import TransLogger
from unittest import TestCase
from webtest import TestApp
from pecan import Pecan, expose, request, response, redirect, abort, make_app, override_template, render
from pecan.templating import _builtin_renderers as builtin_renderers, error_formatters
from pecan.decorators import accept_noncanonical
import os
class SampleRootController(object): pass
class TestBase(TestCase):
def test_simple_app(self):
class RootController(object):
@expose()
def index(self):
return 'Hello, World!'
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
assert r.body == 'Hello, World!'
r = app.get('/index')
assert r.status_int == 200
assert r.body == 'Hello, World!'
r = app.get('/index.html')
assert r.status_int == 200
assert r.body == 'Hello, World!'
def test_controller_lookup_by_string_path(self):
app = Pecan('pecan.tests.test_base.SampleRootController')
assert app.root and isinstance(app.root, SampleRootController)
def test_object_dispatch(self):
class SubSubController(object):
@expose()
def index(self):
return '/sub/sub/'
@expose()
def deeper(self):
return '/sub/sub/deeper'
class SubController(object):
@expose()
def index(self):
return '/sub/'
@expose()
def deeper(self):
return '/sub/deeper'
sub = SubSubController()
class RootController(object):
@expose()
def index(self):
return '/'
@expose()
def deeper(self):
return '/deeper'
sub = SubController()
app = TestApp(Pecan(RootController()))
for path in ('/', '/deeper', '/sub/', '/sub/deeper', '/sub/sub/', '/sub/sub/deeper'):
r = app.get(path)
assert r.status_int == 200
assert r.body == path
def test_lookup(self):
class LookupController(object):
def __init__(self, someID):
self.someID = someID
@expose()
def index(self):
return '/%s' % self.someID
@expose()
def name(self):
return '/%s/name' % self.someID
class RootController(object):
@expose()
def index(self):
return '/'
@expose()
def _lookup(self, someID, *remainder):
return LookupController(someID), remainder
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
assert r.body == '/'
r = app.get('/100/')
assert r.status_int == 200
assert r.body == '/100'
r = app.get('/100/name')
assert r.status_int == 200
assert r.body == '/100/name'
def test_lookup_with_wrong_argspec(self):
class RootController(object):
@expose()
def _lookup(self, someID):
return 'Bad arg spec'
app = TestApp(Pecan(RootController()))
r = app.get('/foo/bar', expect_errors=True)
r.status_int == 404
def test_controller_args(self):
class RootController(object):
@expose()
def index(self, id):
return 'index: %s' % id
@expose()
def multiple(self, one, two):
return 'multiple: %s, %s' % (one, two)
@expose()
def optional(self, id=None):
return 'optional: %s' % str(id)
@expose()
def multiple_optional(self, one=None, two=None, three=None):
return 'multiple_optional: %s, %s, %s' % (one, two, three)
@expose()
def variable_args(self, *args):
return 'variable_args: %s' % ', '.join(args)
@expose()
def variable_kwargs(self, **kwargs):
data = ['%s=%s' % (key, kwargs[key]) for key in sorted(kwargs.keys())]
return 'variable_kwargs: %s' % ', '.join(data)
@expose()
def variable_all(self, *args, **kwargs):
data = ['%s=%s' % (key, kwargs[key]) for key in sorted(kwargs.keys())]
return 'variable_all: %s' % ', '.join(list(args) + data)
@expose()
def eater(self, id, dummy=None, *args, **kwargs):
data = ['%s=%s' % (key, kwargs[key]) for key in sorted(kwargs.keys())]
return 'eater: %s, %s, %s' % (id, dummy, ', '.join(list(args) + data))
@expose()
def _route(self, args):
if hasattr(self, args[0]):
return getattr(self, args[0]), args[1:]
else:
return self.index, args
app = TestApp(Pecan(RootController()))
# required arg
try:
r = app.get('/')
assert r.status_int != 200
except Exception, ex:
assert type(ex) == TypeError
assert ex.args[0] == 'index() takes exactly 2 arguments (1 given)'
r = app.get('/1')
assert r.status_int == 200
assert r.body == 'index: 1'
r = app.get('/This%20is%20a%20test%21')
assert r.status_int == 200
assert r.body == 'index: This is a test!'
r = app.get('/1/dummy', status=404)
assert r.status_int == 404
r = app.get('/?id=2')
assert r.status_int == 200
assert r.body == 'index: 2'
r = app.get('/?id=This%20is%20a%20test%21')
assert r.status_int == 200
assert r.body == 'index: This is a test!'
r = app.get('/3?id=three')
assert r.status_int == 200
assert r.body == 'index: 3'
r = app.get('/This%20is%20a%20test%21?id=three')
assert r.status_int == 200
assert r.body == 'index: This is a test!'
r = app.post('/', {'id': '4'})
assert r.status_int == 200
assert r.body == 'index: 4'
r = app.post('/4', {'id': 'four'})
assert r.status_int == 200
assert r.body == 'index: 4'
r = app.get('/?id=5&dummy=dummy')
assert r.status_int == 200
assert r.body == 'index: 5'
r = app.post('/', {'id': '6', 'dummy': 'dummy'})
assert r.status_int == 200
assert r.body == 'index: 6'
# multiple args
r = app.get('/multiple/one/two')
assert r.status_int == 200
assert r.body == 'multiple: one, two'
r = app.get('/multiple/One%20/Two%21')
assert r.status_int == 200
assert r.body == 'multiple: One , Two!'
r = app.get('/multiple?one=three&two=four')
assert r.status_int == 200
assert r.body == 'multiple: three, four'
r = app.get('/multiple?one=Three%20&two=Four%20%21')
assert r.status_int == 200
assert r.body == 'multiple: Three , Four !'
r = app.post('/multiple', {'one': 'five', 'two': 'six'})
assert r.status_int == 200
assert r.body == 'multiple: five, six'
r = app.post('/multiple', {'one': 'Five%20', 'two': 'Six%20%21'})
assert r.status_int == 200
assert r.body == 'multiple: Five%20, Six%20%21'
# optional arg
r = app.get('/optional')
assert r.status_int == 200
assert r.body == 'optional: None'
r = app.get('/optional/1')
assert r.status_int == 200
assert r.body == 'optional: 1'
r = app.get('/optional/Some%20Number')
assert r.status_int == 200
assert r.body == 'optional: Some Number'
r = app.get('/optional/2/dummy', status=404)
assert r.status_int == 404
r = app.get('/optional?id=2')
assert r.status_int == 200
assert r.body == 'optional: 2'
r = app.get('/optional?id=Some%20Number')
assert r.status_int == 200
assert r.body == 'optional: Some Number'
r = app.get('/optional/3?id=three')
assert r.status_int == 200
assert r.body == 'optional: 3'
r = app.get('/optional/Some%20Number?id=three')
assert r.status_int == 200
assert r.body == 'optional: Some Number'
r = app.post('/optional', {'id': '4'})
assert r.status_int == 200
assert r.body == 'optional: 4'
r = app.post('/optional', {'id': 'Some%20Number'})
assert r.status_int == 200
assert r.body == 'optional: Some%20Number'
r = app.post('/optional/5', {'id': 'five'})
assert r.status_int == 200
assert r.body == 'optional: 5'
r = app.post('/optional/Some%20Number', {'id': 'five'})
assert r.status_int == 200
assert r.body == 'optional: Some Number'
r = app.get('/optional?id=6&dummy=dummy')
assert r.status_int == 200
assert r.body == 'optional: 6'
r = app.get('/optional?id=Some%20Number&dummy=dummy')
assert r.status_int == 200
assert r.body == 'optional: Some Number'
r = app.post('/optional', {'id': '7', 'dummy': 'dummy'})
assert r.status_int == 200
assert r.body == 'optional: 7'
r = app.post('/optional', {'id': 'Some%20Number', 'dummy': 'dummy'})
assert r.status_int == 200
assert r.body == 'optional: Some%20Number'
# multiple optional args
r = app.get('/multiple_optional')
assert r.status_int == 200
assert r.body == 'multiple_optional: None, None, None'
r = app.get('/multiple_optional/1')
assert r.status_int == 200
assert r.body == 'multiple_optional: 1, None, None'
r = app.get('/multiple_optional/One%21')
assert r.status_int == 200
assert r.body == 'multiple_optional: One!, None, None'
r = app.get('/multiple_optional/1/2/3')
assert r.status_int == 200
assert r.body == 'multiple_optional: 1, 2, 3'
r = app.get('/multiple_optional/One%21/Two%21/Three%21')
assert r.status_int == 200
assert r.body == 'multiple_optional: One!, Two!, Three!'
r = app.get('/multiple_optional/1/2/3/dummy', status=404)
assert r.status_int == 404
r = app.get('/multiple_optional?one=1')
assert r.status_int == 200
assert r.body == 'multiple_optional: 1, None, None'
r = app.get('/multiple_optional?one=One%21')
assert r.status_int == 200
assert r.body == 'multiple_optional: One!, None, None'
r = app.get('/multiple_optional/1?one=one')
assert r.status_int == 200
assert r.body == 'multiple_optional: 1, None, None'
r = app.get('/multiple_optional/One%21?one=one')
assert r.status_int == 200
assert r.body == 'multiple_optional: One!, None, None'
r = app.post('/multiple_optional', {'one': '1'})
assert r.status_int == 200
assert r.body == 'multiple_optional: 1, None, None'
r = app.post('/multiple_optional', {'one': 'One%21'})
assert r.status_int == 200
assert r.body == 'multiple_optional: One%21, None, None'
r = app.post('/multiple_optional/1', {'one': 'one'})
assert r.status_int == 200
assert r.body == 'multiple_optional: 1, None, None'
r = app.post('/multiple_optional/One%21', {'one': 'one'})
assert r.status_int == 200
assert r.body == 'multiple_optional: One!, None, None'
r = app.get('/multiple_optional?one=1&two=2&three=3&four=4')
assert r.status_int == 200
assert r.body == 'multiple_optional: 1, 2, 3'
r = app.get('/multiple_optional?one=One%21&two=Two%21&three=Three%21&four=4')
assert r.status_int == 200
assert r.body == 'multiple_optional: One!, Two!, Three!'
r = app.post('/multiple_optional', {'one': '1', 'two': '2', 'three': '3', 'four': '4'})
assert r.status_int == 200
assert r.body == 'multiple_optional: 1, 2, 3'
r = app.post('/multiple_optional', {'one': 'One%21', 'two': 'Two%21', 'three': 'Three%21', 'four': '4'})
assert r.status_int == 200
assert r.body == 'multiple_optional: One%21, Two%21, Three%21'
r = app.get('/multiple_optional?three=3')
assert r.status_int == 200
assert r.body == 'multiple_optional: None, None, 3'
r = app.get('/multiple_optional?three=Three%21')
assert r.status_int == 200
assert r.body == 'multiple_optional: None, None, Three!'
r = app.get('/multiple_optional', {'two': '2'})
assert r.status_int == 200
assert r.body == 'multiple_optional: None, 2, None'
# variable args
r = app.get('/variable_args')
assert r.status_int == 200
assert r.body == 'variable_args: '
r = app.get('/variable_args/1/dummy')
assert r.status_int == 200
assert r.body == 'variable_args: 1, dummy'
r = app.get('/variable_args/Testing%20One%20Two/Three%21')
assert r.status_int == 200
assert r.body == 'variable_args: Testing One Two, Three!'
r = app.get('/variable_args?id=2&dummy=dummy')
assert r.status_int == 200
assert r.body == 'variable_args: '
r = app.post('/variable_args', {'id': '3', 'dummy': 'dummy'})
assert r.status_int == 200
assert r.body == 'variable_args: '
# variable keyword args
r = app.get('/variable_kwargs')
assert r.status_int == 200
assert r.body == 'variable_kwargs: '
r = app.get('/variable_kwargs/1/dummy', status=404)
assert r.status_int == 404
r = app.get('/variable_kwargs?id=2&dummy=dummy')
assert r.status_int == 200
assert r.body == 'variable_kwargs: dummy=dummy, id=2'
r = app.get('/variable_kwargs?id=Two%21&dummy=This%20is%20a%20test')
assert r.status_int == 200
assert r.body == 'variable_kwargs: dummy=This is a test, id=Two!'
r = app.post('/variable_kwargs', {'id': '3', 'dummy': 'dummy'})
assert r.status_int == 200
assert r.body == 'variable_kwargs: dummy=dummy, id=3'
r = app.post('/variable_kwargs', {'id': 'Three%21', 'dummy': 'This%20is%20a%20test'})
assert r.status_int == 200
assert r.body == 'variable_kwargs: dummy=This%20is%20a%20test, id=Three%21'
# variable args & keyword args
r = app.get('/variable_all')
assert r.status_int == 200
assert r.body == 'variable_all: '
r = app.get('/variable_all/1')
assert r.status_int == 200
assert r.body == 'variable_all: 1'
r = app.get('/variable_all/2/dummy')
assert r.status_int == 200
assert r.body == 'variable_all: 2, dummy'
r = app.get('/variable_all/3?month=1&day=12')
assert r.status_int == 200
assert r.body == 'variable_all: 3, day=12, month=1'
r = app.get('/variable_all/4?id=four&month=1&day=12')
assert r.status_int == 200
assert r.body == 'variable_all: 4, day=12, id=four, month=1'
r = app.post('/variable_all/5/dummy')
assert r.status_int == 200
assert r.body == 'variable_all: 5, dummy'
r = app.post('/variable_all/6', {'month': '1', 'day': '12'})
assert r.status_int == 200
assert r.body == 'variable_all: 6, day=12, month=1'
r = app.post('/variable_all/7', {'id': 'seven', 'month': '1', 'day': '12'})
assert r.status_int == 200
assert r.body == 'variable_all: 7, day=12, id=seven, month=1'
# the "everything" controller
try:
r = app.get('/eater')
assert r.status_int != 200
except Exception, ex:
assert type(ex) == TypeError
assert ex.args[0] == 'eater() takes at least 2 arguments (1 given)'
r = app.get('/eater/1')
assert r.status_int == 200
assert r.body == 'eater: 1, None, '
r = app.get('/eater/2/dummy')
assert r.status_int == 200
assert r.body == 'eater: 2, dummy, '
r = app.get('/eater/3/dummy/foo/bar')
assert r.status_int == 200
assert r.body == 'eater: 3, dummy, foo, bar'
r = app.get('/eater/4?month=1&day=12')
assert r.status_int == 200
assert r.body == 'eater: 4, None, day=12, month=1'
r = app.get('/eater/5?id=five&month=1&day=12&dummy=dummy')
assert r.status_int == 200
assert r.body == 'eater: 5, dummy, day=12, month=1'
r = app.post('/eater/6')
assert r.status_int == 200
assert r.body == 'eater: 6, None, '
r = app.post('/eater/7/dummy')
assert r.status_int == 200
assert r.body == 'eater: 7, dummy, '
r = app.post('/eater/8/dummy/foo/bar')
assert r.status_int == 200
assert r.body == 'eater: 8, dummy, foo, bar'
r = app.post('/eater/9', {'month': '1', 'day': '12'})
assert r.status_int == 200
assert r.body == 'eater: 9, None, day=12, month=1'
r = app.post('/eater/10', {'id': 'ten', 'month': '1', 'day': '12', 'dummy': 'dummy'})
assert r.status_int == 200
assert r.body == 'eater: 10, dummy, day=12, month=1'
def test_abort(self):
class RootController(object):
@expose()
def index(self):
abort(404)
app = TestApp(Pecan(RootController()))
r = app.get('/', status=404)
assert r.status_int == 404
def test_abort_with_detail(self):
class RootController(object):
@expose()
def index(self):
abort(status_code=401, detail='Not Authorized')
app = TestApp(Pecan(RootController()))
r = app.get('/', status=401)
assert r.status_int == 401
def test_redirect(self):
class RootController(object):
@expose()
def index(self):
redirect('/testing')
@expose()
def internal(self):
redirect('/testing', internal=True)
@expose()
def bad_internal(self):
redirect('/testing', internal=True, code=301)
@expose()
def permanent(self):
redirect('/testing', code=301)
@expose()
def testing(self):
return 'it worked!'
app = TestApp(make_app(RootController(), debug=True))
r = app.get('/')
assert r.status_int == 302
r = r.follow()
assert r.status_int == 200
assert r.body == 'it worked!'
r = app.get('/internal')
assert r.status_int == 200
assert r.body == 'it worked!'
self.assertRaises(ValueError, app.get, '/bad_internal')
r = app.get('/permanent')
assert r.status_int == 301
r = r.follow()
assert r.status_int == 200
assert r.body == 'it worked!'
def test_x_forward_proto(self):
class ChildController(object):
@expose()
def index(self):
redirect('/testing')
class RootController(object):
@expose()
def index(self):
redirect('/testing')
@expose()
def testing(self):
return 'it worked!'
child = ChildController()
app = TestApp(make_app(RootController(), debug=True))
response = app.get('/child', extra_environ=dict(HTTP_X_FORWARDED_PROTO='https'))
##non-canonical url will redirect, so we won't get a 301
assert response.status_int == 302
##should add trailing / and changes location to https
assert response.location == 'https://localhost/child/'
assert response.request.environ['HTTP_X_FORWARDED_PROTO'] == 'https'
def test_streaming_response(self):
import StringIO
class RootController(object):
@expose(content_type='text/plain')
def test(self, foo):
if foo == 'stream':
# mimic large file
contents = StringIO.StringIO('stream')
response.content_type='application/octet-stream'
contents.seek(0, os.SEEK_END)
response.content_length = contents.tell()
contents.seek(0, os.SEEK_SET)
response.app_iter = contents
return response
else:
return 'plain text'
app = TestApp(Pecan(RootController()))
r = app.get('/test/stream')
assert r.content_type == 'application/octet-stream'
assert r.body == 'stream'
r = app.get('/test/plain')
assert r.content_type == 'text/plain'
assert r.body == 'plain text'
def test_request_state_cleanup(self):
"""
After a request, the state local() should be totally clean
except for state.app (so that objects don't leak between requests)
"""
from pecan.core import state
class RootController(object):
@expose()
def index(self):
return '/'
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
assert r.body == '/'
assert state.__dict__.keys() == ['app']
def test_extension(self):
"""
Test extension splits
"""
class RootController(object):
@expose(content_type=None)
def _default(self, *args):
from pecan.core import request
return request.pecan['extension']
app = TestApp(Pecan(RootController()))
r = app.get('/index.html')
assert r.status_int == 200
assert r.body == '.html'
r = app.get('/image.png')
assert r.status_int == 200
assert r.body == '.png'
r = app.get('/.vimrc')
assert r.status_int == 200
assert r.body == ''
r = app.get('/gradient.js.js')
assert r.status_int == 200
assert r.body == '.js'
def test_app_wrap(self):
class RootController(object):
pass
wrapped_apps = []
def wrap(app):
wrapped_apps.append(app)
return app
app = make_app(RootController(), wrap_app=wrap, debug=True)
assert len(wrapped_apps) == 1
def test_bad_content_type(self):
class RootController(object):
@expose()
def index(self):
return '/'
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
assert r.body == '/'
r = app.get('/index.html', expect_errors=True)
assert r.status_int == 200
assert r.body == '/'
r = app.get('/index.txt', expect_errors=True)
assert r.status_int == 404
def test_canonical_index(self):
class ArgSubController(object):
@expose()
def index(self, arg):
return arg
class AcceptController(object):
@accept_noncanonical
@expose()
def index(self):
return 'accept'
class SubController(object):
@expose()
def index(self, **kw):
return 'subindex'
class RootController(object):
@expose()
def index(self):
return 'index'
sub = SubController()
arg = ArgSubController()
accept = AcceptController()
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
assert 'index' in r.body
r = app.get('/index')
assert r.status_int == 200
assert 'index' in r.body
# for broken clients
r = app.get('', status=302)
assert r.status_int == 302
assert r.location == 'http://localhost/'
r = app.get('/sub/')
assert r.status_int == 200
assert 'subindex' in r.body
r = app.get('/sub', status=302)
assert r.status_int == 302
assert r.location == 'http://localhost/sub/'
# try with query string
r = app.get('/sub?foo=bar', status=302)
assert r.status_int == 302
assert r.location == 'http://localhost/sub/?foo=bar'
try:
r = app.post('/sub', dict(foo=1))
raise Exception, "Post should fail"
except Exception, e:
assert isinstance(e, RuntimeError)
r = app.get('/arg/index/foo')
assert r.status_int == 200
assert r.body == 'foo'
r = app.get('/accept/')
assert r.status_int == 200
assert 'accept' == r.body
r = app.get('/accept')
assert r.status_int == 200
assert 'accept' == r.body
app = TestApp(Pecan(RootController(), force_canonical=False))
r = app.get('/')
assert r.status_int == 200
assert 'index' in r.body
r = app.get('/sub')
assert r.status_int == 200
assert 'subindex' in r.body
r = app.post('/sub', dict(foo=1))
assert r.status_int == 200
assert 'subindex' in r.body
r = app.get('/sub/')
assert r.status_int == 200
assert 'subindex' in r.body
def test_proxy(self):
class RootController(object):
@expose()
def index(self):
request.testing = True
assert request.testing == True
del request.testing
assert hasattr(request, 'testing') == False
return '/'
app = TestApp(make_app(RootController(), debug=True))
r = app.get('/')
assert r.status_int == 200
class TestLogging(TestCase):
"""
Mocks logging calls so we can make sure they get called. We could use
Fudge for this, but it would add an additional dependency to Pecan for
a single set of tests.
"""
def setUp(self):
self._write_log = TransLogger.write_log
def tearDown(self):
TransLogger.write_log = self._write_log
def test_default(self):
class RootController(object):
@expose()
def index(self):
return '/'
# monkeypatch the logger
writes = []
def _write_log(self, *args, **kwargs):
writes.append(1)
TransLogger.write_log = _write_log
# check the request
app = TestApp(make_app(RootController(), debug=True))
r = app.get('/')
assert r.status_int == 200
assert writes == []
def test_default(self):
class RootController(object):
@expose()
def index(self):
return '/'
# monkeypatch the logger
writes = []
def _write_log(self, *args, **kwargs):
writes.append(1)
TransLogger.write_log = _write_log
# check the request
app = TestApp(make_app(RootController(), debug=True))
r = app.get('/')
assert r.status_int == 200
assert len(writes) == 0
def test_no_logging(self):
class RootController(object):
@expose()
def index(self):
return '/'
# monkeypatch the logger
writes = []
def _write_log(self, *args, **kwargs):
writes.append(1)
TransLogger.write_log = _write_log
# check the request
app = TestApp(make_app(RootController(), debug=True, logging=False))
r = app.get('/')
assert r.status_int == 200
assert len(writes) == 0
def test_basic_logging(self):
class RootController(object):
@expose()
def index(self):
return '/'
# monkeypatch the logger
writes = []
def _write_log(self, *args, **kwargs):
writes.append(1)
TransLogger.write_log = _write_log
# check the request
app = TestApp(make_app(RootController(), debug=True, logging=True))
r = app.get('/')
assert r.status_int == 200
assert len(writes) == 1
def test_empty_config(self):
class RootController(object):
@expose()
def index(self):
return '/'
# monkeypatch the logger
writes = []
def _write_log(self, *args, **kwargs):
writes.append(1)
TransLogger.write_log = _write_log
# check the request
app = TestApp(make_app(RootController(), debug=True, logging={}))
r = app.get('/')
assert r.status_int == 200
assert len(writes) == 1
def test_custom_config(self):
class RootController(object):
@expose()
def index(self):
return '/'
# create a custom logger
writes = []
class FakeLogger(object):
def log(self, *args, **kwargs):
writes.append(1)
# check the request
app = TestApp(make_app(RootController(), debug=True,
logging={'logger': FakeLogger()}))
r = app.get('/')
assert r.status_int == 200
assert len(writes) == 1
class TestEngines(TestCase):
template_path = os.path.join(os.path.dirname(__file__), 'templates')
def test_genshi(self):
if 'genshi' not in builtin_renderers:
return
class RootController(object):
@expose('genshi:genshi.html')
def index(self, name='Jonathan'):
return dict(name=name)
@expose('genshi:genshi_bad.html')
def badtemplate(self):
return dict()
app = TestApp(Pecan(RootController(), template_path=self.template_path))
r = app.get('/')
assert r.status_int == 200
assert "<h1>Hello, Jonathan!</h1>" in r.body
r = app.get('/index.html?name=World')
assert r.status_int == 200
assert "<h1>Hello, World!</h1>" in r.body
error_msg = None
try:
r = app.get('/badtemplate.html')
except Exception, e:
for error_f in error_formatters:
error_msg = error_f(e)
if error_msg:
break
assert error_msg is not None
def test_kajiki(self):
if 'kajiki' not in builtin_renderers:
return
class RootController(object):
@expose('kajiki:kajiki.html')
def index(self, name='Jonathan'):
return dict(name=name)
app = TestApp(Pecan(RootController(), template_path=self.template_path))
r = app.get('/')
assert r.status_int == 200
assert "<h1>Hello, Jonathan!</h1>" in r.body
r = app.get('/index.html?name=World')
assert r.status_int == 200
assert "<h1>Hello, World!</h1>" in r.body
def test_jinja(self):
if 'jinja' not in builtin_renderers:
return
class RootController(object):
@expose('jinja:jinja.html')
def index(self, name='Jonathan'):
return dict(name=name)
@expose('jinja:jinja_bad.html')
def badtemplate(self):
return dict()
app = TestApp(Pecan(RootController(), template_path=self.template_path))
r = app.get('/')
assert r.status_int == 200
assert "<h1>Hello, Jonathan!</h1>" in r.body
error_msg = None
try:
r = app.get('/badtemplate.html')
except Exception, e:
for error_f in error_formatters:
error_msg = error_f(e)
if error_msg:
break
assert error_msg is not None
def test_mako(self):
if 'mako' not in builtin_renderers:
return
class RootController(object):
@expose('mako:mako.html')
def index(self, name='Jonathan'):
return dict(name=name)
@expose('mako:mako_bad.html')
def badtemplate(self):
return dict()
app = TestApp(Pecan(RootController(), template_path=self.template_path))
r = app.get('/')
assert r.status_int == 200
assert "<h1>Hello, Jonathan!</h1>" in r.body
r = app.get('/index.html?name=World')
assert r.status_int == 200
assert "<h1>Hello, World!</h1>" in r.body
error_msg = None
try:
r = app.get('/badtemplate.html')
except Exception, e:
for error_f in error_formatters:
error_msg = error_f(e)
if error_msg:
break
assert error_msg is not None
def test_json(self):
try:
from simplejson import loads
except:
from json import loads
expected_result = dict(name='Jonathan', age=30, nested=dict(works=True))
class RootController(object):
@expose('json')
def index(self):
return expected_result
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
result = dict(loads(r.body))
assert result == expected_result
def test_override_template(self):
class RootController(object):
@expose('foo.html')
def index(self):
override_template(None, content_type='text/plain')
return 'Override'
app = TestApp(Pecan(RootController()))
r = app.get('/')
assert r.status_int == 200
assert 'Override' in r.body
assert r.content_type == 'text/plain'
def test_render(self):
#if 'mako' not in builtin_renderers:
# return
class RootController(object):
@expose()
def index(self, name='Jonathan'):
return render('mako.html', dict(name=name))
return dict(name=name)
app = TestApp(Pecan(RootController(), template_path=self.template_path))
r = app.get('/')
assert r.status_int == 200
assert "<h1>Hello, Jonathan!</h1>" in r.body