summaryrefslogtreecommitdiff
path: root/repoze
diff options
context:
space:
mode:
Diffstat (limited to 'repoze')
-rw-r--r--repoze/bfg/tests/test_urldispatch.py39
-rw-r--r--repoze/bfg/tests/test_zcml.py317
-rw-r--r--repoze/bfg/urldispatch.py13
-rw-r--r--repoze/bfg/zcml.py110
4 files changed, 303 insertions, 176 deletions
diff --git a/repoze/bfg/tests/test_urldispatch.py b/repoze/bfg/tests/test_urldispatch.py
index 99d5d1a98..c7dfdf196 100644
--- a/repoze/bfg/tests/test_urldispatch.py
+++ b/repoze/bfg/tests/test_urldispatch.py
@@ -105,6 +105,45 @@ class RoutesRootFactoryTests(unittest.TestCase):
self.assertEqual(request.matchdict, routing_args)
self.failUnless(req_iface.providedBy(request))
+ def test_route_matches_with_predicates(self):
+ root_factory = DummyRootFactory(123)
+ req_iface = self._registerRouteRequest('foo')
+ mapper = self._makeOne(root_factory)
+ mapper.connect('archives/:action/:article', 'foo',
+ predicates=[lambda *arg: True])
+ request = self._getRequest(PATH_INFO='/archives/action1/article1')
+ result = mapper(request)
+ self.assertEqual(result, 123)
+ environ = request.environ
+ routing_args = environ['wsgiorg.routing_args'][1]
+ self.assertEqual(routing_args['action'], 'action1')
+ self.assertEqual(routing_args['article'], 'article1')
+ self.assertEqual(environ['bfg.routes.matchdict'], routing_args)
+ self.assertEqual(environ['bfg.routes.route'].name, 'foo')
+ self.assertEqual(request.matchdict, routing_args)
+ self.failUnless(req_iface.providedBy(request))
+
+ def test_route_fails_to_match_with_predicates(self):
+ root_factory = DummyRootFactory(123)
+ foo_iface = self._registerRouteRequest('foo')
+ bar_iface = self._registerRouteRequest('bar')
+ mapper = self._makeOne(root_factory)
+ mapper.connect('archives/:action/article1', 'foo',
+ predicates=[lambda *arg: True, lambda *arg: False])
+ mapper.connect('archives/:action/:article', 'bar')
+ request = self._getRequest(PATH_INFO='/archives/action1/article1')
+ result = mapper(request)
+ self.assertEqual(result, 123)
+ environ = request.environ
+ routing_args = environ['wsgiorg.routing_args'][1]
+ self.assertEqual(routing_args['action'], 'action1')
+ self.assertEqual(routing_args['article'], 'article1')
+ self.assertEqual(environ['bfg.routes.matchdict'], routing_args)
+ self.assertEqual(environ['bfg.routes.route'].name, 'bar')
+ self.assertEqual(request.matchdict, routing_args)
+ self.failUnless(bar_iface.providedBy(request))
+ self.failIf(foo_iface.providedBy(request))
+
def test_root_route_matches(self):
root_factory = DummyRootFactory(123)
req_iface = self._registerRouteRequest('root')
diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py
index 8106baa03..d534559f6 100644
--- a/repoze/bfg/tests/test_zcml.py
+++ b/repoze/bfg/tests/test_zcml.py
@@ -1542,9 +1542,9 @@ class TestConnectRouteFunction(unittest.TestCase):
def tearDown(self):
cleanUp()
- def _callFUT(self, path, name, factory):
+ def _callFUT(self, path, name, factory, predicates):
from repoze.bfg.zcml import connect_route
- return connect_route(path, name, factory)
+ return connect_route(path, name, factory, predicates)
def _registerRoutesMapper(self):
from zope.component import getSiteManager
@@ -1556,8 +1556,9 @@ class TestConnectRouteFunction(unittest.TestCase):
def test_defaults(self):
mapper = self._registerRoutesMapper()
- self._callFUT('path', 'name', 'factory')
- self.assertEqual(mapper.connections, [('path', 'name', 'factory')])
+ self._callFUT('path', 'name', 'factory', 'predicates')
+ self.assertEqual(mapper.connections, [('path', 'name', 'factory',
+ 'predicates')])
class TestRouteDirective(unittest.TestCase):
def setUp(self):
@@ -1582,10 +1583,12 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(
+ route_discriminator,
+ ('route', 'name', False, None, None, None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
def test_with_view(self):
from zope.interface import Interface
@@ -1622,10 +1625,12 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(
+ route_discriminator,
+ ('route', 'name', False, None, None, None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
def test_with_view_and_view_for(self):
from zope.component import getSiteManager
@@ -1658,10 +1663,11 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None,))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None, None, None,None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
def test_without_view(self):
from repoze.bfg.zcml import connect_route
@@ -1675,10 +1681,9 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None, None, None, None))
+ self.assertEqual(route_args, ('path', 'name', None, []))
def test_with_view_request_type(self):
from zope.component import getSiteManager
@@ -1711,12 +1716,13 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None, None, None,None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
- def test_with_view_request_type_alias(self):
+ def test_with_view_request_method(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -1725,7 +1731,8 @@ class TestRouteDirective(unittest.TestCase):
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view, request_type="GET")
+ self._callFUT(context, 'name', 'path', view=view,
+ view_request_method="GET")
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -1746,12 +1753,13 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None, None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
- def test_with_view_request_method(self):
+ def test_with_view_containment(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -1760,8 +1768,7 @@ class TestRouteDirective(unittest.TestCase):
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view,
- view_request_method="GET")
+ self._callFUT(context, 'name', 'path', view=view, view_containment=True)
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -1771,7 +1778,7 @@ class TestRouteDirective(unittest.TestCase):
sm = getSiteManager()
request_type = sm.getUtility(IRouteRequest, 'name')
view_discriminator = view_action['discriminator']
- discrim = ('view', None, '', request_type, IView, None, None, 'GET',
+ discrim = ('view', None, '', request_type, IView, True, None, None,
'name', None, False, None, None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
@@ -1782,12 +1789,13 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None,None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
- def test_with_view_request_method_alias(self):
+ def test_with_view_header(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -1796,7 +1804,7 @@ class TestRouteDirective(unittest.TestCase):
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view, request_method="GET")
+ self._callFUT(context, 'name', 'path', view=view, view_header='Host')
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -1805,10 +1813,45 @@ class TestRouteDirective(unittest.TestCase):
register()
sm = getSiteManager()
request_type = sm.getUtility(IRouteRequest, 'name')
+ view_discriminator = view_action['discriminator']
+ discrim = ('view', None, '', request_type, IView, None, None, None,
+ 'name', None, False, None, 'Host', None)
+ self.assertEqual(view_discriminator, discrim)
+ wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
+ self.failUnless(wrapped)
+
+ route_action = actions[1]
+ route_callable = route_action['callable']
+ route_discriminator = route_action['discriminator']
+ route_args = route_action['args']
+ self.assertEqual(route_callable, connect_route)
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None,None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
+ def test_with_view_path_info(self):
+ from zope.component import getSiteManager
+ from repoze.bfg.zcml import connect_route
+ from repoze.bfg.interfaces import IView
+ from repoze.bfg.interfaces import IRouteRequest
+
+ context = DummyContext()
+ def view(context, request):
+ """ """
+ self._callFUT(context, 'name', 'path', view=view, view_path_info='/foo')
+ actions = context.actions
+ self.assertEqual(len(actions), 2)
+
+ view_action = actions[0]
+ register = view_action['callable']
+ register()
+ sm = getSiteManager()
+ request_type = sm.getUtility(IRouteRequest, 'name')
view_discriminator = view_action['discriminator']
- discrim = ('view', None, '', request_type, IView, None, None, 'GET',
- 'name', None, False, None, None, None)
+ discrim = ('view', None, '', request_type, IView, None, None, None,
+ 'name', None, False, None, None, '/foo')
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -1818,12 +1861,13 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None, None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
- def test_with_view_containment(self):
+ def test_with_view_xhr(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -1832,7 +1876,7 @@ class TestRouteDirective(unittest.TestCase):
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view, view_containment=True)
+ self._callFUT(context, 'name', 'path', view=view, view_xhr=True)
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -1842,8 +1886,8 @@ class TestRouteDirective(unittest.TestCase):
sm = getSiteManager()
request_type = sm.getUtility(IRouteRequest, 'name')
view_discriminator = view_action['discriminator']
- discrim = ('view', None, '', request_type, IView, True, None, None,
- 'name', None, False, None, None, None)
+ discrim = ('view', None, '', request_type, IView, None, None, None,
+ 'name', None, True, None, None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -1853,12 +1897,13 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None, None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
- def test_with_view_containment_alias(self):
+ def test_with_view_accept(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -1867,7 +1912,8 @@ class TestRouteDirective(unittest.TestCase):
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view, containment=True)
+ self._callFUT(context, 'name', 'path', view=view,
+ view_accept='text/xml')
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -1877,8 +1923,8 @@ class TestRouteDirective(unittest.TestCase):
sm = getSiteManager()
request_type = sm.getUtility(IRouteRequest, 'name')
view_discriminator = view_action['discriminator']
- discrim = ('view', None, '', request_type, IView, True, None, None,
- 'name', None, False, None, None, None)
+ discrim = ('view', None, '', request_type, IView, None, None, None,
+ 'name', None, False, 'text/xml', None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -1888,12 +1934,14 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(
+ route_discriminator,
+ ('route', 'name', False, None, None, None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
- def test_with_view_header(self):
+ def test_with_request_type_GET(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -1902,7 +1950,7 @@ class TestRouteDirective(unittest.TestCase):
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view, view_header='Host')
+ self._callFUT(context, 'name', 'path', view=view, request_type="GET")
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -1912,8 +1960,8 @@ class TestRouteDirective(unittest.TestCase):
sm = getSiteManager()
request_type = sm.getUtility(IRouteRequest, 'name')
view_discriminator = view_action['discriminator']
- discrim = ('view', None, '', request_type, IView, None, None, None,
- 'name', None, False, None, 'Host', None)
+ discrim = ('view', None, '', request_type, IView, None, None, 'GET',
+ 'name', None, False, None, None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -1923,12 +1971,15 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None, None, None,None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 0)
+
+ # route predicates
- def test_with_view_header_alias(self):
+ def test_with_xhr(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -1937,7 +1988,7 @@ class TestRouteDirective(unittest.TestCase):
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view, header='Host')
+ self._callFUT(context, 'name', 'path', view=view, xhr=True)
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -1948,7 +1999,7 @@ class TestRouteDirective(unittest.TestCase):
request_type = sm.getUtility(IRouteRequest, 'name')
view_discriminator = view_action['discriminator']
discrim = ('view', None, '', request_type, IView, None, None, None,
- 'name', None, False, None, 'Host', None)
+ 'name', None, False, None, None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -1958,21 +2009,25 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', True, None, None, None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 1)
+ request = DummyRequest()
+ request.is_xhr = True
+ self.assertEqual(predicates[0](None, request), True)
- def test_with_view_path_info(self):
+ def test_with_request_method(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
from repoze.bfg.interfaces import IRouteRequest
-
+
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view, view_path_info='/foo')
+ self._callFUT(context, 'name', 'path', view=view, request_method="GET")
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -1981,9 +2036,10 @@ class TestRouteDirective(unittest.TestCase):
register()
sm = getSiteManager()
request_type = sm.getUtility(IRouteRequest, 'name')
+
view_discriminator = view_action['discriminator']
discrim = ('view', None, '', request_type, IView, None, None, None,
- 'name', None, False, None, None, '/foo')
+ 'name', None, False, None, None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -1993,21 +2049,25 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, 'GET',None, None, None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 1)
+ request = DummyRequest()
+ request.method = 'GET'
+ self.assertEqual(predicates[0](None, request), True)
- def test_with_view_xhr(self):
+ def test_with_path_info(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
from repoze.bfg.interfaces import IRouteRequest
-
+
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view, view_xhr=True)
+ self._callFUT(context, 'name', 'path', view=view, path_info='/foo')
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -2018,7 +2078,7 @@ class TestRouteDirective(unittest.TestCase):
request_type = sm.getUtility(IRouteRequest, 'name')
view_discriminator = view_action['discriminator']
discrim = ('view', None, '', request_type, IView, None, None, None,
- 'name', None, True, None, None, None)
+ 'name', None, False, None, None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -2028,12 +2088,16 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, '/foo',None,None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 1)
+ request = DummyRequest()
+ request.path_info = '/foo'
+ self.assertEqual(predicates[0](None, request), True)
- def test_with_view_xhr_alias(self):
+ def test_with_request_param(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -2042,7 +2106,7 @@ class TestRouteDirective(unittest.TestCase):
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view, xhr=True)
+ self._callFUT(context, 'name', 'path', view=view, request_param='abc')
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -2053,7 +2117,7 @@ class TestRouteDirective(unittest.TestCase):
request_type = sm.getUtility(IRouteRequest, 'name')
view_discriminator = view_action['discriminator']
discrim = ('view', None, '', request_type, IView, None, None, None,
- 'name', None, True, None, None, None)
+ 'name', None, False, None, None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -2063,12 +2127,16 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None,'abc', None, None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 1)
+ request = DummyRequest()
+ request.params = {'abc':'123'}
+ self.assertEqual(predicates[0](None, request), True)
- def test_with_view_accept(self):
+ def test_with_header(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -2077,8 +2145,7 @@ class TestRouteDirective(unittest.TestCase):
context = DummyContext()
def view(context, request):
""" """
- self._callFUT(context, 'name', 'path', view=view,
- view_accept='text/xml')
+ self._callFUT(context, 'name', 'path', view=view, header='Host')
actions = context.actions
self.assertEqual(len(actions), 2)
@@ -2089,7 +2156,7 @@ class TestRouteDirective(unittest.TestCase):
request_type = sm.getUtility(IRouteRequest, 'name')
view_discriminator = view_action['discriminator']
discrim = ('view', None, '', request_type, IView, None, None, None,
- 'name', None, False, 'text/xml', None, None)
+ 'name', None, False, None, None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -2099,12 +2166,16 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(route_discriminator,
+ ('route', 'name', False, None, None,None,'Host', None))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 1)
+ request = DummyRequest()
+ request.headers = {'Host':'example.com'}
+ self.assertEqual(predicates[0](None, request), True)
- def test_with_view_accept_alias(self):
+ def test_with_accept(self):
from zope.component import getSiteManager
from repoze.bfg.zcml import connect_route
from repoze.bfg.interfaces import IView
@@ -2125,7 +2196,7 @@ class TestRouteDirective(unittest.TestCase):
view_discriminator = view_action['discriminator']
discrim = ('view', None, '', request_type, IView, None, None, None,
- 'name', None, False, 'text/xml', None, None)
+ 'name', None, False, None, None, None)
self.assertEqual(view_discriminator, discrim)
wrapped = sm.adapters.lookup((IDummy, request_type), IView, name='')
self.failUnless(wrapped)
@@ -2135,10 +2206,15 @@ class TestRouteDirective(unittest.TestCase):
route_discriminator = route_action['discriminator']
route_args = route_action['args']
self.assertEqual(route_callable, connect_route)
- self.assertEqual(len(route_discriminator), 2)
- self.assertEqual(route_discriminator[0], 'route')
- self.assertEqual(route_discriminator[1], 'name')
- self.assertEqual(route_args, ('path', 'name', None))
+ self.assertEqual(
+ route_discriminator,
+ ('route', 'name', False, None, None, None, None, 'text/xml'))
+ self.assertEqual(route_args[:3], ('path', 'name', None))
+ predicates = route_args[3]
+ self.assertEqual(len(predicates), 1)
+ request = DummyRequest()
+ request.accept = ['text/xml']
+ self.assertEqual(predicates[0](None, request), True)
class TestStaticDirective(unittest.TestCase):
def setUp(self):
@@ -2186,7 +2262,8 @@ class TestStaticDirective(unittest.TestCase):
discriminator = action['discriminator']
args = action['args']
self.assertEqual(callable, connect_route)
- self.assertEqual(discriminator, ('route', 'name'))
+ self.assertEqual(discriminator,
+ ('route', 'name', False, None, None, None, None, None))
self.assertEqual(args[0], 'name*subpath')
def test_package_relative(self):
@@ -2220,7 +2297,8 @@ class TestStaticDirective(unittest.TestCase):
discriminator = action['discriminator']
args = action['args']
self.assertEqual(callable, connect_route)
- self.assertEqual(discriminator, ('route', 'name'))
+ self.assertEqual(discriminator,
+ ('route', 'name', False, None, None, None, None, None))
self.assertEqual(args[0], 'name*subpath')
def test_here_relative(self):
@@ -2255,7 +2333,8 @@ class TestStaticDirective(unittest.TestCase):
discriminator = action['discriminator']
args = action['args']
self.assertEqual(callable, connect_route)
- self.assertEqual(discriminator, ('route', 'name'))
+ self.assertEqual(discriminator,
+ ('route', 'name', False, None, None, None, None, None))
self.assertEqual(args[0], 'name*subpath')
class TestResourceDirective(unittest.TestCase):
@@ -2564,8 +2643,8 @@ class DummyMapper:
def __init__(self):
self.connections = []
- def connect(self, *args):
- self.connections.append(args)
+ def connect(self, path, name, factory, predicates=()):
+ self.connections.append((path, name, factory, predicates))
class DummyRoute:
pass
diff --git a/repoze/bfg/urldispatch.py b/repoze/bfg/urldispatch.py
index 4088cef12..185baa1a1 100644
--- a/repoze/bfg/urldispatch.py
+++ b/repoze/bfg/urldispatch.py
@@ -5,18 +5,20 @@ from zope.interface import directlyProvides
from repoze.bfg.interfaces import IRouteRequest
+from repoze.bfg.compat import all
+from repoze.bfg.encode import url_quote
from repoze.bfg.traversal import traversal_path
from repoze.bfg.traversal import quote_path_segment
-from repoze.bfg.encode import url_quote
_marker = object()
class Route(object):
- def __init__(self, path, name=None, factory=None):
+ def __init__(self, path, name=None, factory=None, predicates=()):
self.path = path
self.match, self.generate = _compile_route(path)
self.name = name
self.factory = factory
+ self.predicates = predicates
class RoutesRootFactory(object):
def __init__(self, default_root_factory):
@@ -30,8 +32,8 @@ class RoutesRootFactory(object):
def get_routes(self):
return self.routelist
- def connect(self, path, name, factory=None):
- route = Route(path, name, factory)
+ def connect(self, path, name, factory=None, predicates=()):
+ route = Route(path, name, factory, predicates)
self.routelist.append(route)
self.routes[name] = route
return route
@@ -69,6 +71,9 @@ class RoutesRootFactory(object):
for route in self.routelist:
match = route.match(path)
if match is not None:
+ preds = route.predicates
+ if preds and not all((p(None, request) for p in preds)):
+ continue
environ['wsgiorg.routing_args'] = ((), match)
environ['bfg.routes.route'] = route
environ['bfg.routes.matchdict'] = match
diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py
index c39f06bb3..97af9112a 100644
--- a/repoze/bfg/zcml.py
+++ b/repoze/bfg/zcml.py
@@ -197,7 +197,7 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
except re.error, why:
raise ConfigurationError(why[0])
def path_info_predicate(context, request):
- return path_info_val.match(request.path_info)
+ return path_info_val.match(request.path_info) is not None
weight = weight - 30
predicates.append(path_info_predicate)
@@ -553,9 +553,19 @@ class IRouteDirective(Interface):
path = TextLine(title=u'path', required=True)
factory = GlobalObject(title=u'context factory', required=False)
view = GlobalObject(title=u'view', required=False)
+
view_for = GlobalObject(title=u'view_for', required=False)
+ # alias for view_for
+ for_ = GlobalObject(title=u'for', required=False)
+
view_permission = TextLine(title=u'view_permission', required=False)
+ # alias for view_permission
+ permission = TextLine(title=u'permission', required=False)
+
view_request_type = TextLine(title=u'view_request_type', required=False)
+ # alias for view_request_type
+ request_type = TextLine(title=u'request_type', required=False)
+
view_request_method = TextLine(title=u'view_request_method', required=False)
view_containment = GlobalObject(
title = u'Dotted name of a containment class or interface',
@@ -566,31 +576,12 @@ class IRouteDirective(Interface):
view_accept = TextLine(title=u'view_accept', required=False)
view_xhr = Bool(title=u'view_xhr', required=False)
view_path_info = TextLine(title=u'view_path_info', required=False)
- # alias for "view_for"
- for_ = GlobalObject(title=u'for', required=False)
- # alias for "view_permission"
- permission = TextLine(title=u'permission', required=False)
- # alias for "view_request_type"
- request_type = TextLine(title=u'request_type', required=False)
- # alias for "view_request_method"
+
request_method = TextLine(title=u'request_method', required=False)
- # alias for "view_request_param"
request_param = TextLine(title=u'request_param', required=False)
- # alias for "view_containment"
- containment = GlobalObject(
- title = u'Dotted name of a containment class or interface',
- required=False)
- # alias for "view_attr"
- attr = TextLine(title=u'attr', required=False)
- # alias for "view_renderer"
- renderer = TextLine(title=u'renderer', required=False)
- # alias for "view_header"
header = TextLine(title=u'header', required=False)
- # alias for "view_accept"
accept = TextLine(title=u'accept', required=False)
- # alias for "view_xhr"
xhr = Bool(title=u'xhr', required=False)
- # alias for "view_path_info"
path_info = TextLine(title=u'path_info', required=False)
class IRouteRequirementDirective(Interface):
@@ -601,59 +592,72 @@ class IRouteRequirementDirective(Interface):
def route(_context, name, path, view=None, view_for=None,
permission=None, factory=None, request_type=None, for_=None,
+ header=None, xhr=False, accept=None, path_info=None,
view_permission=None, view_request_type=None,
request_method=None, view_request_method=None,
- request_param=None, view_request_param=None, containment=None,
- view_containment=None, attr=None, view_attr=None, renderer=None,
- view_renderer=None, header=None, view_header=None, accept=None,
- view_accept=None, xhr=False, view_xhr=False,
- path_info=None, view_path_info=None):
+ request_param=None, view_request_param=None,
+ view_containment=None, view_attr=None,
+ view_renderer=None, view_header=None,
+ view_accept=None, view_xhr=False,
+ view_path_info=None):
""" Handle ``route`` ZCML directives
"""
# the strange ordering of the request kw args above is for b/w
# compatibility purposes.
- for_ = view_for or for_
- request_type = view_request_type or request_type
- permission = view_permission or permission
- request_method = view_request_method or request_method
- request_param = view_request_param or request_param
- containment = view_containment or containment
- attr = view_attr or attr
- renderer = view_renderer or renderer
- header = view_header or header
- accept = view_accept or accept
- xhr = view_xhr or xhr
- path_info = view_path_info or path_info
+ # these are route predicates; if they do not match, the next route
+ # in the routelist will be tried
+ _, predicates = _make_predicates(xhr=xhr,
+ request_method=request_method,
+ path_info=path_info,
+ request_param=request_param,
+ header=header,
+ accept=accept)
sm = getSiteManager()
if request_type in ('GET', 'HEAD', 'PUT', 'POST', 'DELETE'):
# b/w compat for 1.0
- request_method = request_type
+ view_request_method = request_type
request_type = None
- if request_type is None:
- request_type = queryUtility(IRouteRequest, name=name)
- if request_type is None:
- request_type = route_request_iface(name)
- sm.registerUtility(request_type, IRouteRequest, name=name)
+ request_iface = queryUtility(IRouteRequest, name=name)
+ if request_iface is None:
+ request_iface = route_request_iface(name)
+ sm.registerUtility(request_iface, IRouteRequest, name=name)
if view:
- _view(_context, permission=permission, for_=for_, view=view, name='',
- request_type=request_type, route_name=name,
- request_method=request_method, request_param=request_param,
- containment=containment, attr=attr, renderer=renderer,
- header=header, accept=accept, xhr=xhr, path_info=path_info)
+ view_for = view_for or for_
+ view_request_type = view_request_type or request_type
+ view_permission = view_permission or permission
+ _view(
+ _context,
+ permission=view_permission,
+ for_=view_for,
+ view=view,
+ name='',
+ request_type=view_request_type,
+ route_name=name,
+ request_method=view_request_method,
+ request_param=view_request_param,
+ containment=view_containment,
+ attr=view_attr,
+ renderer=view_renderer,
+ header=view_header,
+ accept=view_accept,
+ xhr=view_xhr,
+ path_info=view_path_info,
+ )
_context.action(
- discriminator = ('route', name),
+ discriminator = ('route', name, xhr, request_method, path_info,
+ request_param, header, accept),
callable = connect_route,
- args = (path, name, factory),
+ args = (path, name, factory, predicates),
)
-def connect_route(path, name, factory):
+def connect_route(path, name, factory, predicates):
mapper = getUtility(IRoutesMapper)
- mapper.connect(path, name, factory)
+ mapper.connect(path, name, factory, predicates=predicates)
class IRendererDirective(Interface):
factory = GlobalObject(