Permalink
Browse files

Merge branch 'feature.usemetapredicates'

  • Loading branch information...
2 parents 7d5cf83 + ec556f4 commit 1e45dd9da51ac607eb2afc5df4f813f9608b981f @mcdonc mcdonc committed Aug 7, 2012
Showing with 110 additions and 32 deletions.
  1. +1 −1 setup.py
  2. +13 −1 substanced/content/__init__.py
  3. +26 −0 substanced/content/tests.py
  4. +64 −22 substanced/sdi/__init__.py
  5. +6 −8 substanced/sdi/tests/test_sdi.py
View
@@ -24,7 +24,7 @@
README = CHANGES = ''
install_requires = [
- 'pyramid',
+ 'pyramid>=1.4dev',
'ZODB3',
'hypatia>=0.1a2',
'venusian',
@@ -167,7 +167,19 @@ def add_provides(*arg, **kw):
add_provides.__orig__ = factory
return add_provides
+class ContentTypePredicate(object):
+ def __init__(self, val, config):
+ self.val = val
+
+ def text(self):
+ return 'content_type = %s' % (self.val,)
+
+ phash = text
+
+ def __call__(self, context, request):
+ return get_content_type(context) == self.val
+
def includeme(config): # pragma: no cover
config.registry.content = ContentRegistry()
config.add_directive('add_content_type', add_content_type)
-
+ config.add_view_predicate('content_type', ContentTypePredicate)
@@ -238,6 +238,32 @@ def factory():
self.assertTrue(IDummy.providedBy(ob))
self.assertTrue(IDummy in directlyProvidedBy(ob))
+class TestContentTypePredicate(unittest.TestCase):
+ def _makeOne(self, val):
+ from . import ContentTypePredicate
+ return ContentTypePredicate(val, None)
+
+ def test___call___true(self):
+ inst = self._makeOne('abc')
+ context = Dummy()
+ context.__content_type__ = 'abc'
+ result = inst(context, None)
+ self.assertTrue(result)
+
+ def test___call___false(self):
+ inst = self._makeOne(True)
+ context = Dummy()
+ result = inst(context, None)
+ self.assertFalse(result)
+
+ def test_text(self):
+ inst = self._makeOne('abc')
+ self.assertEqual(inst.text(), 'content_type = abc')
+
+ def test_phash(self):
+ inst = self._makeOne('abc')
+ self.assertEqual(inst.phash(), 'content_type = abc')
+
class DummyContentRegistry(object):
def __init__(self):
self.added = []
View
@@ -13,11 +13,14 @@
from pyramid.compat import is_nonstr_iter
from pyramid.exceptions import ConfigurationError
from pyramid.httpexceptions import HTTPBadRequest
-from pyramid.interfaces import IView
from pyramid.request import Request
from pyramid.security import authenticated_userid
from pyramid.session import UnencryptedCookieSessionFactoryConfig
from pyramid.traversal import resource_path_tuple
+from pyramid.registry import (
+ predvalseq,
+ Deferred,
+ )
from ..service import find_service
@@ -36,40 +39,79 @@ def check_csrf_token(request, token='csrf_token'):
@viewdefaults
@action_method
def add_mgmt_view(
- config, view=None, name="", permission=None, request_method=None,
- request_param=None, containment=None, attr=None, renderer=None,
- wrapper=None, xhr=False, accept=None, header=None, path_info=None,
- custom_predicates=(), context=None, decorator=None, mapper=None,
- http_cache=None, match_param=None, request_type=None, tab_title=None,
- tab_condition=None, check_csrf=False, csrf_token='csrf_token',
- ):
+ config,
+ view=None,
+ name="",
+ permission=None,
+ request_method=None,
+ request_param=None,
+ containment=None,
+ attr=None,
+ renderer=None,
+ wrapper=None,
+ xhr=False,
+ accept=None,
+ header=None,
+ path_info=None,
+ custom_predicates=(),
+ context=None,
+ decorator=None,
+ mapper=None,
+ http_cache=None,
+ match_param=None,
+ request_type=None,
+ tab_title=None,
+ tab_condition=None,
+ check_csrf=False,
+ csrf_token='csrf_token',
+ **other_predicates
+ ):
+
view = config.maybe_dotted(view)
context = config.maybe_dotted(context)
containment = config.maybe_dotted(containment)
mapper = config.maybe_dotted(mapper)
decorator = config.maybe_dotted(decorator)
- if request_method is not None:
- request_method = as_sorted_tuple(request_method)
- if 'GET' in request_method and 'HEAD' not in request_method:
- # GET implies HEAD too
- request_method = as_sorted_tuple(request_method + ('HEAD',))
-
if check_csrf:
def _check_csrf_token(context, request):
check_csrf_token(request, csrf_token)
return True
custom_predicates = tuple(custom_predicates) + (_check_csrf_token,)
route_name = MANAGE_ROUTE_NAME
- view_discriminator = [
- 'view', context, name, request_type, IView, containment,
- request_param, request_method, route_name, attr,
- xhr, accept, header, path_info, match_param]
- view_discriminator.extend(sorted([hash(x) for x in custom_predicates]))
- view_discriminator = tuple(view_discriminator)
-
- discriminator = ('sdi view',) + view_discriminator[1:]
+
+ pvals = other_predicates
+ pvals.update(
+ dict(
+ xhr=xhr,
+ request_method=request_method,
+ path_info=path_info,
+ request_param=request_param,
+ header=header,
+ accept=accept,
+ containment=containment,
+ request_type=request_type,
+ match_param=match_param,
+ custom=predvalseq(custom_predicates),
+ )
+ )
+
+ predlist = config.view_predlist
+
+ def view_discrim_func():
+ # We need to defer the discriminator until we know what the phash
+ # is. It can't be computed any sooner because thirdparty
+ # predicates may not yet exist when add_view is called.
+ order, preds, phash = predlist.make(config, **pvals)
+ return ('view', context, name, route_name, phash)
+
+ def sdi_view_discrim_func():
+ order, preds, phash = predlist.make(config, **pvals)
+ return ('sdi view', context, name, route_name, phash)
+
+ view_discriminator = Deferred(view_discrim_func)
+ discriminator = Deferred(sdi_view_discrim_func)
if inspect.isclass(view) and attr:
view_desc = 'method %r of %s' % (attr, config.object_description(view))
@@ -25,16 +25,10 @@ def _makeConfig(self):
config = DummyConfigurator()
return config
- def test_with_request_method_sorted(self):
+ def test_with_request_method(self):
config = self._makeConfig()
self._callFUT(config, request_method=('HEAD', 'GET'))
- self.assertEqual(config._added['request_method'], ('GET', 'HEAD'))
- self.assertTrue(config._actions)
-
- def test_with_request_method_get_implies_head(self):
- config = self._makeConfig()
- self._callFUT(config, request_method='GET')
- self.assertEqual(config._added['request_method'], ('GET', 'HEAD'))
+ self.assertEqual(config._added['request_method'], ('HEAD', 'GET'))
self.assertTrue(config._actions)
def test_with_check_csrf(self):
@@ -648,12 +642,16 @@ def attach(self, wrapped, callback, category):
self.category = category
return self.info
+class DummyPredicateList(object):
+ pass
+
class DummyConfigurator(object):
_ainfo = None
def __init__(self):
self._intr = DummyIntrospectable()
self._actions = []
self._added = None
+ self.view_predlist = DummyPredicateList()
def object_description(self, ob):
return ob

0 comments on commit 1e45dd9

Please sign in to comment.