summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcguardia <carlos.delaguardia@gmail.com>2011-05-04 15:11:59 -0500
committercguardia <carlos.delaguardia@gmail.com>2011-05-04 15:11:59 -0500
commit8abf0a3c996a22dbf9b3ed4602df026a87686a74 (patch)
tree72f9c5390e0f4c34893e48a057982872dfd322de
parent542794624ead6bf96ae052421374493c851edd4f (diff)
downloadpyramid-8abf0a3c996a22dbf9b3ed4602df026a87686a74.tar.gz
pyramid-8abf0a3c996a22dbf9b3ed4602df026a87686a74.tar.bz2
pyramid-8abf0a3c996a22dbf9b3ed4602df026a87686a74.zip
code refactoring for showing route->view relationship more correctly; tests and docs for pull request
-rw-r--r--docs/narr/urldispatch.rst4
-rw-r--r--docs/narr/viewconfig.rst97
-rw-r--r--pyramid/config.py31
-rw-r--r--pyramid/paster.py132
-rw-r--r--pyramid/tests/test_config.py22
-rw-r--r--pyramid/tests/test_paster.py153
6 files changed, 328 insertions, 111 deletions
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index 1024dd188..a180003d0 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -1121,6 +1121,10 @@ a developer to understand either of them in detail. It also means that we
can allow a developer to combine :term:`URL dispatch` and :term:`traversal`
in various exceptional cases as documented in :ref:`hybrid_chapter`.
+To gain a better understanding of how routes and views are associated in a
+real application, you can use the ``paster pviews`` command, as documented
+in :ref:`displaying_matching_views`.
+
References
----------
diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst
index 743cc016e..d99e5bed5 100644
--- a/docs/narr/viewconfig.rst
+++ b/docs/narr/viewconfig.rst
@@ -732,3 +732,100 @@ found will be printed to ``stderr``, and the browser representation of the
error will include the same information. See :ref:`environment_chapter` for
more information about how, and where to set these values.
+.. index::
+ pair: matching views; printing
+ single: paster pviews
+
+.. _displaying_matching_views:
+
+Displaying Matching Views for a Given URL
+-----------------------------------------
+
+For a big application with several views, it can be hard to keep the view
+configuration details in your head, even if you defined all the views
+yourself. You can use the ``paster pviews`` command in a terminal window to
+print a summary of matching routes and views for a given URL in your
+application. The ``paster pviews`` command accepts three arguments. The
+first argument to ``pviews`` is the path to your application's ``.ini`` file.
+The second is the ``app`` section name inside the ``.ini`` file which points
+to your application. The third is the URL to test for matching views.
+
+Here is an example for a simple view configuration using :term:`traversal`:
+
+.. code-block:: text
+ :linenos:
+
+ $ ../bin/paster pviews development.ini tutorial /FrontPage
+
+ URL = /FrontPage
+
+ context: <tutorial.models.Page object at 0xa12536c>
+ view name:
+
+ View:
+ -----
+ tutorial.views.view_page
+ required permission = view
+
+The output always has the requested URL at the top and below that all the
+views that matched with their view configuration details. In this example
+only one view matches, so there is just a single *View* section. For each
+matching view, the full code path to the associated view callable is shown,
+along with any permissions and predicates that are part of that view
+configuration.
+
+A more complex configuration might generate something like this:
+
+.. code-block:: text
+ :linenos:
+
+ $ ../bin/paster pviews development.ini shootout /about
+
+ URL = /about
+
+ context: <shootout.models.RootFactory object at 0xa56668c>
+ view name: about
+
+ Route:
+ ------
+ route name: about
+ route pattern: /about
+ route path: /about
+ subpath:
+ route predicates (request method = GET)
+
+ View:
+ -----
+ shootout.views.about_view
+ required permission = view
+ view predicates (request_param testing, header X/header)
+
+ Route:
+ ------
+ route name: about_post
+ route pattern: /about
+ route path: /about
+ subpath:
+ route predicates (request method = POST)
+
+ View:
+ -----
+ shootout.views.about_view_post
+ required permission = view
+ view predicates (request_param test)
+
+ View:
+ -----
+ shootout.views.about_view_post2
+ required permission = view
+ view predicates (request_param test2)
+
+In this case, we are dealing with a :term:`URL dispatch` application. This
+specific URL has two matching routes. The matching route information is
+displayed first, followed by any views that are associated with that route.
+As you can see from the second matching route output, a route can be
+associated with more than one view.
+
+For a URL that doesn't match any views, ``paster pviews`` will simply print
+out a *Not found* message.
+
diff --git a/pyramid/config.py b/pyramid/config.py
index 9aa7031e0..ca76cafb4 100644
--- a/pyramid/config.py
+++ b/pyramid/config.py
@@ -2485,16 +2485,17 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
if xhr:
def xhr_predicate(context, request):
- """xhr = True"""
return request.is_xhr
+ xhr_predicate.__text__ = "xhr = True"
weights.append(1 << 1)
predicates.append(xhr_predicate)
h.update('xhr:%r' % bool(xhr))
if request_method is not None:
def request_method_predicate(context, request):
- """request_method = %s""" % request_method
return request.method == request_method
+ text = "request method = %s"
+ request_method_predicate.__text__ = text % request_method
weights.append(1 << 2)
predicates.append(request_method_predicate)
h.update('request_method:%r' % request_method)
@@ -2505,8 +2506,9 @@ 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):
- """path_info = %s""" % path_info
return path_info_val.match(request.path_info) is not None
+ text = "path_info = %s"
+ path_info_predicate.__text__ = text % path_info
weights.append(1 << 3)
predicates.append(path_info_predicate)
h.update('path_info:%r' % path_info)
@@ -2516,14 +2518,14 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
if '=' in request_param:
request_param, request_param_val = request_param.split('=', 1)
if request_param_val is None:
- msg = "request_param %s" % request_param
+ text = "request_param %s" % request_param
else:
- msg = "request_param %s = %s" % (request_param, request_param_val)
+ text = "request_param %s = %s" % (request_param, request_param_val)
def request_param_predicate(context, request):
- """%s""" % msg
if request_param_val is None:
return request_param in request.params
return request.params.get(request_param) == request_param_val
+ request_param_predicate.__text__ = text
weights.append(1 << 4)
predicates.append(request_param_predicate)
h.update('request_param:%r=%r' % (request_param, request_param_val))
@@ -2538,41 +2540,42 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
except re.error, why:
raise ConfigurationError(why[0])
if header_val is None:
- msg = "header %s" % header_name
+ text = "header %s" % header_name
else:
- msg = "header %s = %s" % (header_name, header_val)
+ text = "header %s = %s" % (header_name, header_val)
def header_predicate(context, request):
- """%s""" % msg
if header_val is None:
return header_name in request.headers
val = request.headers.get(header_name)
if val is None:
return False
return header_val.match(val) is not None
+ header_predicate.__text__ = text
weights.append(1 << 5)
predicates.append(header_predicate)
h.update('header:%r=%r' % (header_name, header_val))
if accept is not None:
def accept_predicate(context, request):
- """accept = %s""" % accept
return accept in request.accept
+ accept_predicate.__text__ = "accept = %s" % accept
weights.append(1 << 6)
predicates.append(accept_predicate)
h.update('accept:%r' % accept)
if containment is not None:
def containment_predicate(context, request):
- """containment = %s""" % containment
return find_interface(context, containment) is not None
+ containment_predicate.__text__ = "containment = %s" % containment
weights.append(1 << 7)
predicates.append(containment_predicate)
h.update('containment:%r' % hash(containment))
if request_type is not None:
def request_type_predicate(context, request):
- """request_type = %s""" % request_type
return request_type.providedBy(request)
+ text = "request_type = %s"
+ request_type_predicate.__text__ = text % request_type
weights.append(1 << 8)
predicates.append(request_type_predicate)
h.update('request_type:%r' % hash(request_type))
@@ -2600,8 +2603,8 @@ def _make_predicates(xhr=None, request_method=None, path_info=None,
if custom:
for num, predicate in enumerate(custom):
- if getattr(predicate, '__doc__', None) is None:
- predicate.__doc__ = "<unknown custom predicate>"
+ if getattr(predicate, '__text__', None) is None:
+ predicate.__text__ = "<unknown custom predicate>"
predicates.append(predicate)
# using hash() here rather than id() is intentional: we
# want to allow custom predicates that are part of
diff --git a/pyramid/paster.py b/pyramid/paster.py
index 15a50458a..f82246fea 100644
--- a/pyramid/paster.py
+++ b/pyramid/paster.py
@@ -201,6 +201,9 @@ class PRoutesCommand(PCommand):
IView, name='', default=None)
self.out(fmt % (route.name, route.pattern, view_callable))
+
+from pyramid.interfaces import IMultiView
+
class PViewsCommand(PCommand):
"""Print, for a given URL, the views that might match. Underneath each
potentially matching route, list the predicates required. Underneath
@@ -260,10 +263,9 @@ class PViewsCommand(PCommand):
from pyramid.interfaces import IRouteRequest
from pyramid.interfaces import IRequestFactory
from pyramid.interfaces import IRoutesMapper
- from pyramid.interfaces import ITraverser
- from pyramid.interfaces import IMultiView
from pyramid.interfaces import IView
from pyramid.interfaces import IViewClassifier
+ from pyramid.interfaces import ITraverser
from pyramid.request import Request
from pyramid.traversal import DefaultRootFactory
from pyramid.traversal import ResourceTreeTraverser
@@ -279,7 +281,7 @@ class PViewsCommand(PCommand):
class RoutesMultiView(object):
implements(IMultiView)
- def __init__(self, infos, context_iface, subpath):
+ def __init__(self, infos, context_iface, root_factory, request):
self.views = []
for info in infos:
match, route = info['match'], info['route']
@@ -293,11 +295,18 @@ class PViewsCommand(PCommand):
IView, name='', default=None)
if view is None:
continue
- view.__predicates__ = list(route.predicates)
- view.__route_attrs__ = {'matchdict': match,
- 'matched_route': route,
- 'subpath': subpath}
- view.__view_attr__ = ''
+ view.__request_attrs__ = {}
+ view.__request_attrs__['matchdict'] = match
+ view.__request_attrs__['matched_route'] = route
+ root_factory = route.factory or root_factory
+ root = root_factory(request)
+ traverser = adapters.queryAdapter(root, ITraverser)
+ if traverser is None:
+ traverser = ResourceTreeTraverser(root)
+ tdict = traverser(request)
+ view.__request_attrs__.update(tdict)
+ if not hasattr(view, '__view_attr__'):
+ view.__view_attr__ = ''
self.views.append((None, view, None))
@@ -355,7 +364,7 @@ class PViewsCommand(PCommand):
(IViewClassifier, request_iface, context_iface),
IView, name=view_name, default=None)
else:
- view = RoutesMultiView(infos, context_iface, subpath)
+ view = RoutesMultiView(infos, context_iface, root_factory, request)
# routes are not registered with a view name
if view is None:
@@ -371,58 +380,52 @@ class PViewsCommand(PCommand):
return view
- def output_route_attrs(self, attrs):
- if 'matched_route' in attrs:
- route = attrs['matched_route']
- self.out(" route name: %s" % route.name)
- self.out(" route pattern: %s" % route.pattern)
- self.out(" route path: %s" % route.path)
- self.out(" subpath: %s" % '/'.join(attrs['subpath']))
-
- def output_view_attrs(self, attrs):
- self.out(" context: %s" % attrs['context'])
- self.out(" view name: %s" % attrs['view_name'])
-
- def output_multiview_info(self, view_wrapper):
- name = view_wrapper.__name__
- module = view_wrapper.__module__
- attr = view_wrapper.__view_attr__
- route_attrs = getattr(view_wrapper, '__route_attrs__', {})
- self.out('')
- self.out(" View:")
- self.out(" -----")
- self.out(" %s.%s.%s" % (module, name, attr))
- self.output_route_attrs(route_attrs)
- permission = getattr(view_wrapper, '__permission__', None)
- if permission is not None:
- self.out(" required permission = %s" % permission)
- predicates = getattr(view_wrapper, '__predicates__', None)
- if predicates is not None:
- for predicate in predicates:
- self.out(" %s" % predicate.__doc__)
-
- def output_view_info(self, view):
- if view is not None:
- name = getattr(view, '__name__', view.__class__.__name__)
- module = view.__module__
+ def output_route_attrs(self, attrs, indent):
+ route = attrs['matched_route']
+ self.out("%sroute name: %s" % (indent, route.name))
+ self.out("%sroute pattern: %s" % (indent, route.pattern))
+ self.out("%sroute path: %s" % (indent, route.path))
+ self.out("%ssubpath: %s" % (indent, '/'.join(attrs['subpath'])))
+ predicates = ', '.join([p.__text__ for p in route.predicates])
+ if predicates != '':
+ self.out("%sroute predicates (%s)" % (indent, predicates))
+
+ def output_view_info(self, view_wrapper, level=1):
+ indent = " " * level
+ name = getattr(view_wrapper, '__name__', '')
+ module = getattr(view_wrapper, '__module__', '')
+ attr = getattr(view_wrapper, '__view_attr__', None)
+ request_attrs = getattr(view_wrapper, '__request_attrs__', {})
+ if attr is not None:
+ view_callable = "%s.%s.%s" % (module, name, attr)
else:
- module = 'Not found'
- name = ''
+ attr = view_wrapper.__class__.__name__
+ if attr == 'function':
+ attr = name
+ view_callable = "%s.%s" % (module, attr)
self.out('')
- self.out(" View:")
- self.out(" -----")
- self.out(" %s.%s" % (module, name))
- permission = getattr(view, '__permission__', None)
- if permission is not None:
- self.out(" required permission = %s" % permission)
- predicates = getattr(view, '__predicates__', None)
- if predicates is not None:
- for predicate in predicates:
- self.out(" %s" % predicate.__doc__)
+ if 'matched_route' in request_attrs:
+ self.out("%sRoute:" % indent)
+ self.out("%s------" % indent)
+ self.output_route_attrs(request_attrs, indent)
+ permission = getattr(view_wrapper, '__permission__', None)
+ if not IMultiView.providedBy(view_wrapper):
+ # single view for this route, so repeat call without route data
+ del request_attrs['matched_route']
+ self.output_view_info(view_wrapper, level+1)
+ else:
+ self.out("%sView:" % indent)
+ self.out("%s-----" % indent)
+ self.out("%s%s" % (indent, view_callable))
+ permission = getattr(view_wrapper, '__permission__', None)
+ if permission is not None:
+ self.out("%srequired permission = %s" % (indent, permission))
+ predicates = getattr(view_wrapper, '__predicates__', None)
+ if predicates is not None:
+ predicate_text = ', '.join([p.__text__ for p in predicates])
+ self.out("%sview predicates (%s)" % (indent, predicate_text))
def command(self):
- from pyramid.interfaces import IMultiView
-
config_file, section_name, url = self.args
if not url.startswith('/'):
url = '/%s' % url
@@ -431,13 +434,20 @@ class PViewsCommand(PCommand):
view = self._find_view(url, registry)
self.out('')
self.out("URL = %s" % url)
+ self.out('')
if view is not None:
- self.output_view_attrs(view.__request_attrs__)
- self.output_route_attrs(view.__request_attrs__)
+ self.out(" context: %s" % view.__request_attrs__['context'])
+ self.out(" view name: %s" % view.__request_attrs__['view_name'])
if IMultiView.providedBy(view):
for dummy, view_wrapper, dummy in view.views:
- self.output_multiview_info(view_wrapper)
+ self.output_view_info(view_wrapper)
+ if IMultiView.providedBy(view_wrapper):
+ for dummy, mv_view_wrapper, dummy in view_wrapper.views:
+ self.output_view_info(mv_view_wrapper, level=2)
else:
- self.output_view_info(view)
+ if view is not None:
+ self.output_view_info(view)
+ else:
+ self.out(" Not found.")
self.out('')
diff --git a/pyramid/tests/test_config.py b/pyramid/tests/test_config.py
index 2bd24ac26..f583cc783 100644
--- a/pyramid/tests/test_config.py
+++ b/pyramid/tests/test_config.py
@@ -4477,6 +4477,28 @@ class Test__make_predicates(unittest.TestCase):
self.assertEqual(info, {'match':
{'a':'a', 'b':'b', 'traverse':('1', 'a', 'b')}})
+ def test_predicate_text_is_correct(self):
+ _, predicates, _ = self._callFUT(
+ xhr='xhr',
+ request_method='request_method',
+ path_info='path_info',
+ request_param='param',
+ header='header',
+ accept='accept',
+ containment='containment',
+ request_type='request_type',
+ custom=(DummyCustomPredicate(),))
+ self.assertEqual(predicates[0].__text__, 'xhr = True')
+ self.assertEqual(predicates[1].__text__,
+ 'request method = request_method')
+ self.assertEqual(predicates[2].__text__, 'path_info = path_info')
+ self.assertEqual(predicates[3].__text__, 'request_param param')
+ self.assertEqual(predicates[4].__text__, 'header header')
+ self.assertEqual(predicates[5].__text__, 'accept = accept')
+ self.assertEqual(predicates[6].__text__, 'containment = containment')
+ self.assertEqual(predicates[7].__text__, 'request_type = request_type')
+ self.assertEqual(predicates[8].__text__, '<unknown custom predicate>')
+
class TestMultiView(unittest.TestCase):
def _getTargetClass(self):
from pyramid.config import MultiView
diff --git a/pyramid/tests/test_paster.py b/pyramid/tests/test_paster.py
index 8a5ef7003..2239d81ea 100644
--- a/pyramid/tests/test_paster.py
+++ b/pyramid/tests/test_paster.py
@@ -545,7 +545,7 @@ class TestPViewsCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(L[1], 'URL = /a')
- self.assertEqual(L[5], ' Not found.')
+ self.assertEqual(L[3], ' Not found.')
def test_views_command_not_found_url_starts_without_slash(self):
from pyramid.registry import Registry
@@ -562,7 +562,7 @@ class TestPViewsCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(L[1], 'URL = /a')
- self.assertEqual(L[5], ' Not found.')
+ self.assertEqual(L[3], ' Not found.')
def test_views_command_single_view_traversal(self):
from pyramid.registry import Registry
@@ -580,9 +580,30 @@ class TestPViewsCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(L[1], 'URL = /a')
- self.assertEqual(L[2], ' context: context')
- self.assertEqual(L[3], ' view name: a')
- self.assertEqual(L[7], ' pyramid.tests.test_paster.DummyView')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[8], ' pyramid.tests.test_paster.DummyView')
+
+ def test_views_command_single_view_function_traversal(self):
+ from pyramid.registry import Registry
+ command = self._makeOne()
+ registry = Registry()
+ L = []
+ command.out = L.append
+ def view(): pass
+ view.__request_attrs__ = {'context': 'context', 'view_name': 'a'}
+ command._find_view = lambda arg1, arg2: view
+ app = DummyApp()
+ app.registry = registry
+ loadapp = DummyLoadApp(app)
+ command.loadapp = (loadapp,)
+ command.args = ('/foo/bar/myapp.ini', 'myapp', '/a')
+ result = command.command()
+ self.assertEqual(result, None)
+ self.assertEqual(L[1], 'URL = /a')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[8], ' pyramid.tests.test_paster.view')
def test_views_command_single_view_traversal_with_permission(self):
from pyramid.registry import Registry
@@ -601,10 +622,10 @@ class TestPViewsCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(L[1], 'URL = /a')
- self.assertEqual(L[2], ' context: context')
- self.assertEqual(L[3], ' view name: a')
- self.assertEqual(L[7], ' pyramid.tests.test_paster.DummyView')
- self.assertEqual(L[8], ' required permission = test')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[8], ' pyramid.tests.test_paster.DummyView')
+ self.assertEqual(L[9], ' required permission = test')
def test_views_command_single_view_traversal_with_predicates(self):
from pyramid.registry import Registry
@@ -612,8 +633,8 @@ class TestPViewsCommand(unittest.TestCase):
registry = Registry()
L = []
command.out = L.append
- def predicate():
- """predicate = x"""
+ def predicate(): pass
+ predicate.__text__ = "predicate = x"
view = DummyView(context='context', view_name='a')
view.__predicates__ = [predicate]
command._find_view = lambda arg1, arg2: view
@@ -625,10 +646,10 @@ class TestPViewsCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(L[1], 'URL = /a')
- self.assertEqual(L[2], ' context: context')
- self.assertEqual(L[3], ' view name: a')
- self.assertEqual(L[7], ' pyramid.tests.test_paster.DummyView')
- self.assertEqual(L[8], ' predicate = x')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[8], ' pyramid.tests.test_paster.DummyView')
+ self.assertEqual(L[9], ' view predicates (predicate = x)')
def test_views_command_single_view_route(self):
from pyramid.registry import Registry
@@ -648,13 +669,70 @@ class TestPViewsCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(L[1], 'URL = /a')
- self.assertEqual(L[2], ' context: context')
- self.assertEqual(L[3], ' view name: a')
- self.assertEqual(L[4], ' route name: a')
- self.assertEqual(L[5], ' route pattern: /a')
- self.assertEqual(L[6], ' route path: /a')
- self.assertEqual(L[7], ' subpath: ')
- self.assertEqual(L[11], ' pyramid.tests.test_paster.DummyView')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[6], ' Route:')
+ self.assertEqual(L[8], ' route name: a')
+ self.assertEqual(L[9], ' route pattern: /a')
+ self.assertEqual(L[10], ' route path: /a')
+ self.assertEqual(L[11], ' subpath: ')
+ self.assertEqual(L[15], ' pyramid.tests.test_paster.DummyView')
+
+ def test_views_command_multi_view_nested(self):
+ from pyramid.registry import Registry
+ command = self._makeOne()
+ registry = Registry()
+ L = []
+ command.out = L.append
+ view1 = DummyView(context='context', view_name='a1')
+ view1.__name__ = 'view1'
+ view1.__view_attr__ = 'call'
+ multiview1 = DummyMultiView(view1, context='context', view_name='a1')
+ multiview2 = DummyMultiView(multiview1, context='context',
+ view_name='a')
+ command._find_view = lambda arg1, arg2: multiview2
+ app = DummyApp()
+ app.registry = registry
+ loadapp = DummyLoadApp(app)
+ command.loadapp = (loadapp,)
+ command.args = ('/foo/bar/myapp.ini', 'myapp', '/a')
+ result = command.command()
+ self.assertEqual(result, None)
+ self.assertEqual(L[1], 'URL = /a')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[8], ' pyramid.tests.test_paster.DummyMultiView')
+ self.assertEqual(L[12], ' pyramid.tests.test_paster.view1.call')
+
+ def test_views_command_single_view_route_with_route_predicates(self):
+ from pyramid.registry import Registry
+ command = self._makeOne()
+ registry = Registry()
+ L = []
+ command.out = L.append
+ def predicate(): pass
+ predicate.__text__ = "predicate = x"
+ route = DummyRoute('a', '/a', matchdict={}, predicate=predicate)
+ view = DummyView(context='context', view_name='a',
+ matched_route=route, subpath='')
+ command._find_view = lambda arg1, arg2: view
+ app = DummyApp()
+ app.registry = registry
+ loadapp = DummyLoadApp(app)
+ command.loadapp = (loadapp,)
+ command.args = ('/foo/bar/myapp.ini', 'myapp', '/a')
+ result = command.command()
+ self.assertEqual(result, None)
+ self.assertEqual(L[1], 'URL = /a')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[6], ' Route:')
+ self.assertEqual(L[8], ' route name: a')
+ self.assertEqual(L[9], ' route pattern: /a')
+ self.assertEqual(L[10], ' route path: /a')
+ self.assertEqual(L[11], ' subpath: ')
+ self.assertEqual(L[12], ' route predicates (predicate = x)')
+ self.assertEqual(L[16], ' pyramid.tests.test_paster.DummyView')
def test_views_command_multiview(self):
from pyramid.registry import Registry
@@ -675,9 +753,9 @@ class TestPViewsCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(L[1], 'URL = /a')
- self.assertEqual(L[2], ' context: context')
- self.assertEqual(L[3], ' view name: a')
- self.assertEqual(L[7], ' pyramid.tests.test_paster.view.call')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[8], ' pyramid.tests.test_paster.view.call')
def test_views_command_multiview_with_permission(self):
from pyramid.registry import Registry
@@ -699,10 +777,10 @@ class TestPViewsCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(L[1], 'URL = /a')
- self.assertEqual(L[2], ' context: context')
- self.assertEqual(L[3], ' view name: a')
- self.assertEqual(L[7], ' pyramid.tests.test_paster.view.call')
- self.assertEqual(L[8], ' required permission = test')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[8], ' pyramid.tests.test_paster.view.call')
+ self.assertEqual(L[9], ' required permission = test')
def test_views_command_multiview_with_predicates(self):
from pyramid.registry import Registry
@@ -710,8 +788,8 @@ class TestPViewsCommand(unittest.TestCase):
registry = Registry()
L = []
command.out = L.append
- def predicate():
- """predicate = x"""
+ def predicate(): pass
+ predicate.__text__ = "predicate = x"
view = DummyView(context='context')
view.__name__ = 'view'
view.__view_attr__ = 'call'
@@ -726,10 +804,10 @@ class TestPViewsCommand(unittest.TestCase):
result = command.command()
self.assertEqual(result, None)
self.assertEqual(L[1], 'URL = /a')
- self.assertEqual(L[2], ' context: context')
- self.assertEqual(L[3], ' view name: a')
- self.assertEqual(L[7], ' pyramid.tests.test_paster.view.call')
- self.assertEqual(L[8], ' predicate = x')
+ self.assertEqual(L[3], ' context: context')
+ self.assertEqual(L[4], ' view name: a')
+ self.assertEqual(L[8], ' pyramid.tests.test_paster.view.call')
+ self.assertEqual(L[9], ' view predicates (predicate = x)')
def _register_mapper(self, registry, routes):
from pyramid.interfaces import IRoutesMapper
@@ -823,13 +901,16 @@ class DummyMapper(object):
return self.routes
class DummyRoute(object):
- def __init__(self, name, pattern, factory=None, matchdict=None):
+ def __init__(self, name, pattern, factory=None,
+ matchdict=None, predicate=None):
self.name = name
self.path = pattern
self.pattern = pattern
self.factory = factory
self.matchdict = matchdict
self.predicates = []
+ if predicate is not None:
+ self.predicates = [predicate]
def match(self, route):
return self.matchdict