1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
import unittest
import bottle
class TestRouter(unittest.TestCase):
CGI=False
def setUp(self):
self.r = bottle.Router()
def add(self, path, target, method='GET', **ka):
self.r.add(path, method, target, **ka)
def match(self, path, method='GET'):
env = {'PATH_INFO': path, 'REQUEST_METHOD': method}
if self.CGI:
env['wsgi.run_once'] = 'true'
return self.r.match(env)
def assertMatches(self, rule, url, method='GET', **args):
self.add(rule, rule, method)
target, urlargs = self.match(url, method)
self.assertEqual(rule, target)
self.assertEqual(args, urlargs)
def testBasic(self):
self.assertMatches('/static', '/static')
self.assertMatches('/\\:its/:#.+#/:test/:name#[a-z]+#/',
'/:its/a/cruel/world/',
test='cruel', name='world')
self.assertMatches('/:test', '/test', test='test') # No tail
self.assertMatches(':test/', 'test/', test='test') # No head
self.assertMatches('/:test/', '/test/', test='test') # Middle
self.assertMatches(':test', 'test', test='test') # Full wildcard
self.assertMatches('/:#anon#/match', '/anon/match') # Anon wildcards
self.assertRaises(bottle.HTTPError, self.match, '//no/m/at/ch/')
def testNewSyntax(self):
self.assertMatches('/static', '/static')
self.assertMatches('/\\<its>/<:re:.+>/<test>/<name:re:[a-z]+>/',
'/<its>/a/cruel/world/',
test='cruel', name='world')
self.assertMatches('/<test>', '/test', test='test') # No tail
self.assertMatches('<test>/', 'test/', test='test') # No head
self.assertMatches('/<test>/', '/test/', test='test') # Middle
self.assertMatches('<test>', 'test', test='test') # Full wildcard
self.assertMatches('/<:re:anon>/match', '/anon/match') # Anon wildcards
self.assertRaises(bottle.HTTPError, self.match, '//no/m/at/ch/')
def testValueErrorInFilter(self):
self.r.add_filter('test', lambda x: ('.*', int, int))
self.assertMatches('/int/<i:test>', '/int/5', i=5) # No tail
self.assertRaises(bottle.HTTPError, self.match, '/int/noint')
def testIntFilter(self):
self.assertMatches('/object/<id:int>', '/object/567', id=567)
self.assertRaises(bottle.HTTPError, self.match, '/object/abc')
def testFloatFilter(self):
self.assertMatches('/object/<id:float>', '/object/1', id=1)
self.assertMatches('/object/<id:float>', '/object/1.1', id=1.1)
self.assertMatches('/object/<id:float>', '/object/.1', id=0.1)
self.assertMatches('/object/<id:float>', '/object/1.', id=1)
self.assertRaises(bottle.HTTPError, self.match, '/object/abc')
self.assertRaises(bottle.HTTPError, self.match, '/object/')
self.assertRaises(bottle.HTTPError, self.match, '/object/.')
def testWildcardNames(self):
self.assertMatches('/alpha/:abc', '/alpha/alpha', abc='alpha')
self.assertMatches('/alnum/:md5', '/alnum/sha1', md5='sha1')
def testParentheses(self):
self.assertMatches('/func(:param)', '/func(foo)', param='foo')
self.assertMatches('/func2(:param#(foo|bar)#)', '/func2(foo)', param='foo')
self.assertMatches('/func2(:param#(foo|bar)#)', '/func2(bar)', param='bar')
self.assertRaises(bottle.HTTPError, self.match, '/func2(baz)')
def testErrorInPattern(self):
self.assertRaises(Exception, self.assertMatches, '/:bug#(#/', '/foo/')
def testBuild(self):
add, build = self.add, self.r.build
add('/:test/:name#[a-z]+#/', 'handler', name='testroute')
url = build('testroute', test='hello', name='world')
self.assertEqual('/hello/world/', url)
url = build('testroute', test='hello', name='world', q='value')
self.assertEqual('/hello/world/?q=value', url)
# RouteBuildError: Missing URL argument: 'test'
self.assertRaises(bottle.RouteBuildError, build, 'test')
def testBuildAnon(self):
add, build = self.add, self.r.build
add('/anon/:#.#', 'handler', name='anonroute')
url = build('anonroute', 'hello')
self.assertEqual('/anon/hello', url)
url = build('anonroute', 'hello', q='value')
self.assertEqual('/anon/hello?q=value', url)
# RouteBuildError: Missing URL argument: anon0.
self.assertRaises(bottle.RouteBuildError, build, 'anonroute')
def testBuildFilter(self):
add, build = self.add, self.r.build
add('/int/<:int>', 'handler', name='introute')
url = build('introute', '5')
self.assertEqual('/int/5', url)
# RouteBuildError: Missing URL argument: anon0.
self.assertRaises(ValueError, build, 'introute', 'hello')
def test_method(self):
#TODO Test method handling. This is done in the router now.
pass
class TestRouterInCGIMode(TestRouter):
''' Makes no sense since the default route does not optimize CGI anymore.'''
CGI = True
if __name__ == '__main__': #pragma: no cover
unittest.main()
|