diff options
author | Marcel Hellkamp <marc@gsites.de> | 2009-07-13 12:24:30 +0200 |
---|---|---|
committer | Marcel Hellkamp <marc@gsites.de> | 2009-07-13 13:20:43 +0200 |
commit | 3da3db5b3f6418821a5a1aa2d17de1f21fc1767f (patch) | |
tree | 97e368034642a7b7ef6a041589e0d5fe0ebbfe98 | |
parent | 8ad8e6122afadec6a6377b70f209f72556f4802c (diff) | |
download | bottle-3da3db5b3f6418821a5a1aa2d17de1f21fc1767f.tar.gz |
New 'nobreak' statement for SimpleTemplate, minor routing changes and some unit tests.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | MANIFEST.in | 1 | ||||
-rw-r--r-- | bottle.py | 18 | ||||
-rw-r--r-- | test/test_routes.py | 38 | ||||
-rw-r--r-- | test/test_templates.py | 46 | ||||
-rw-r--r-- | test/testall.py | 17 |
6 files changed, 112 insertions, 9 deletions
@@ -7,4 +7,3 @@ release.sh *.db MANIFEST benchmark.py -test* diff --git a/MANIFEST.in b/MANIFEST.in index b28c1e8..91adff4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,3 +4,4 @@ include README.* include docs/*.html include examples/*.py include examples/*.tpl +include test/*.py @@ -383,17 +383,16 @@ def compile_route(route): A more human readable syntax is supported too. Example: '/user/:id/:action' will match '/user/5/kiss' with {'id':'5', 'action':'kiss'} """ - route = route.strip().lstrip('$^/ ').rstrip('$^ ') route = re.sub(r':([a-zA-Z_]+)(?P<uniq>[^\w/])(?P<re>.+?)(?P=uniq)',r'(?P<\1>\g<re>)',route) route = re.sub(r':([a-zA-Z_]+)',r'(?P<\1>[^/]+)', route) - return re.compile('^/%s$' % route) + return re.compile('^%s$' % route) def match_url(url, method='GET'): """Returns the first matching handler and a parameter dict or (None, None). This reorders the ROUTING_REGEXP list every 1000 requests. To turn this off, use OPTIMIZER=False""" - url = '/' + url.strip().lstrip("/") + url = url.strip().lstrip("/ ") # Search for static routes first route = ROUTES_SIMPLE.get(method,{}).get(url,None) if route: @@ -421,7 +420,8 @@ def add_route(route, handler, method='GET', simple=False): return "Hello world!" add_route(r'/hello', hello)""" method = method.strip().upper() - if re.match(r'^/(\w+/)*\w*$', route) or simple: + route = route.strip().lstrip('$^/ ').rstrip('$^ ') + if re.match(r'^(\w+/)*\w*$', route) or simple: ROUTES_SIMPLE.setdefault(method, {})[route] = handler else: route = compile_route(route) @@ -618,15 +618,17 @@ class SimpleTemplate(BaseTemplate): self.subtemplates = {} class PyStmt(str): def __repr__(self): return 'str(' + self + ')' - def flush(): - if len(strbuffer): - code.append(" " * indent + "stdout.append(%s)" % repr(''.join(strbuffer))) + def flush(allow_nobreak=False): + bfr = ''.join(strbuffer) + if len(bfr): + if allow_nobreak and bfr.endswith("\\\\\n"): bfr=bfr[:-3] + code.append(" " * indent + "stdout.append(%s)" % repr(bfr)) code.append("\n" * len(strbuffer)) # to preserve line numbers del strbuffer[:] for line in template.splitlines(True): m = self.re_python.match(line) if m: - flush() + flush(allow_nobreak=True) keyword, include, end, statement = m.groups() if keyword: if keyword in self.dedent_keywords: diff --git a/test/test_routes.py b/test/test_routes.py new file mode 100644 index 0000000..7aa0b32 --- /dev/null +++ b/test/test_routes.py @@ -0,0 +1,38 @@ +import unittest +import sys, os.path +TESTDIR = os.path.dirname(os.path.abspath(__file__)) +DISTDIR = os.path.dirname(TESTDIR) +sys.path.insert(0, TESTDIR) +sys.path.insert(0, DISTDIR) + +from bottle import route, add_route, match_url, compile_route, ROUTES_REGEXP, ROUTES_SIMPLE + +class TestRoutes(unittest.TestCase): + + def test_static(self): + """ Routes: Static routes """ + token = 'abc' + routes = ['','/','/abc','abc','/abc/','/abc/def','/abc/def.ghi'] + for r in routes: + add_route(r, token, simple=True) + self.assertTrue('GET' in ROUTES_SIMPLE) + r = [r for r in ROUTES_SIMPLE['GET'].values() if r == 'abc'] + self.assertEqual(5, len(r)) + for r in routes: + self.assertEqual(token, match_url(r)[0]) + + def test_dynamic(self): + """ Routes: Dynamic routes """ + token = 'abcd' + add_route('/:a/:b', token) + self.assertTrue('GET' in ROUTES_REGEXP) + self.assertEqual(token, match_url('/aa/bb')[0]) + self.assertEqual(None, match_url('/aa')[0]) + self.assertEqual(repr({'a':'aa','b':'bb'}), repr(match_url('/aa/bb')[1])) + + +suite = unittest.TestSuite() +suite.addTest(unittest.makeSuite(TestRoutes)) + +if __name__ == '__main__': + unittest.main() diff --git a/test/test_templates.py b/test/test_templates.py new file mode 100644 index 0000000..42d88bb --- /dev/null +++ b/test/test_templates.py @@ -0,0 +1,46 @@ +import unittest +import sys, os.path +TESTDIR = os.path.dirname(os.path.abspath(__file__)) +DISTDIR = os.path.dirname(TESTDIR) +sys.path.insert(0, TESTDIR) +sys.path.insert(0, DISTDIR) + +from bottle import SimpleTemplate + +class TestSimpleTemplate(unittest.TestCase): + + def test_inline(self): + """ Templates: Inline statements """ + t = SimpleTemplate('start {{var}} end') + self.assertEqual('start True end', t.render(var=True)) + self.assertEqual('start False end', t.render(var=False)) + self.assertEqual('start None end', t.render(var=None)) + self.assertEqual('start 0 end', t.render(var=0)) + self.assertEqual('start 5 end', t.render(var=5)) + self.assertEqual('start b end', t.render(var='b')) + self.assertEqual('start 1.0 end', t.render(var=1.0)) + self.assertEqual('start [1, 2] end', t.render(var=[1,2])) + + def test_blocks(self): + """ Templates: Code blocks and loops """ + t = SimpleTemplate("start\n%for i in l:\n{{i}} \n%end\nend") + self.assertEqual('start\n1 \n2 \n3 \nend', t.render(l=[1,2,3])) + self.assertEqual('start\nend', t.render(l=[])) + + def test_nobreak(self): + """ Templates: Nobreak statements""" + t = SimpleTemplate("start\\\\\n%pass\nend") + self.assertEqual('startend', t.render()) + + def test_nonobreak(self): + """ Templates: Escaped nobreak statements""" + t = SimpleTemplate("start\\\\\n\\\\\n%pass\nend") + self.assertEqual('start\\\\\nend', t.render()) + +suite = unittest.TestSuite() +suite.addTest(unittest.makeSuite(TestSimpleTemplate)) + + +if __name__ == '__main__': + unittest.main() + diff --git a/test/testall.py b/test/testall.py new file mode 100644 index 0000000..4e71066 --- /dev/null +++ b/test/testall.py @@ -0,0 +1,17 @@ +import unittest +import sys, os.path +TESTDIR = os.path.dirname(os.path.abspath(__file__)) +DISTDIR = os.path.dirname(TESTDIR) +sys.path.insert(0, TESTDIR) +sys.path.insert(0, DISTDIR) + +from test_templates import suite as suite1 +from test_routes import suite as suite2 + +suite = unittest.TestSuite() +suite.addTest(suite1) +suite.addTest(suite2) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) + |