summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-11-30 17:32:55 -0500
committerChris McDonough <chrism@plope.com>2011-11-30 17:32:55 -0500
commit2e651ed3c6cae62f1d7e9829e3f86f258dce133b (patch)
tree1d05bf7b0c087a0bd7abdb25463275a8cb4a7366
parent57a9d679eb78e774c271bf68f6e805dc2b8186c4 (diff)
downloadpyramid-2e651ed3c6cae62f1d7e9829e3f86f258dce133b.tar.gz
pyramid-2e651ed3c6cae62f1d7e9829e3f86f258dce133b.tar.bz2
pyramid-2e651ed3c6cae62f1d7e9829e3f86f258dce133b.zip
more tests for introspectables
-rw-r--r--pyramid/config/__init__.py18
-rw-r--r--pyramid/interfaces.py13
-rw-r--r--pyramid/tests/test_config/test_init.py205
-rw-r--r--pyramid/tests/test_config/test_util.py10
-rw-r--r--pyramid/tests/test_util.py4
5 files changed, 221 insertions, 29 deletions
diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py
index d4dc0247f..31f35e5ff 100644
--- a/pyramid/config/__init__.py
+++ b/pyramid/config/__init__.py
@@ -69,7 +69,10 @@ from pyramid.config.security import SecurityConfiguratorMixin
from pyramid.config.settings import SettingsConfiguratorMixin
from pyramid.config.testing import TestingConfiguratorMixin
from pyramid.config.tweens import TweensConfiguratorMixin
-from pyramid.config.util import action_method
+from pyramid.config.util import (
+ action_method,
+ ActionInfo,
+ )
from pyramid.config.views import ViewsConfiguratorMixin
from pyramid.config.zca import ZCAConfiguratorMixin
@@ -491,7 +494,7 @@ class Configurator(
if self._ainfo:
info = self._ainfo[0]
else:
- info = ''
+ info = ActionInfo('<unknown>', 0, '<unknown>', '<unknown>')
return info
def action(self, discriminator, callable=None, args=(), kw=None, order=None,
@@ -918,7 +921,7 @@ class ActionState(object):
return True
def action(self, discriminator, callable=None, args=(), kw=None, order=None,
- includepath=(), info='', introspectables=()):
+ includepath=(), info=None, introspectables=()):
"""Add an action with the given discriminator, callable and arguments
"""
if kw is None:
@@ -976,13 +979,11 @@ class ActionState(object):
in:
oops
-
Note that actions executed before the error still have an effect:
>>> output
[('f', (1,), {}), ('f', (2,), {})]
-
"""
try:
@@ -992,10 +993,9 @@ class ActionState(object):
kw = action['kw']
info = action['info']
introspectables = action['introspectables']
- if callable is None:
- continue
try:
- callable(*args, **kw)
+ if callable is not None:
+ callable(*args, **kw)
except (KeyboardInterrupt, SystemExit): # pragma: no cover
raise
except:
@@ -1073,7 +1073,7 @@ def resolveConflicts(actions):
return output
def expand_action(discriminator, callable=None, args=(), kw=None,
- includepath=(), info='', order=None, introspectables=()):
+ includepath=(), info=None, order=None, introspectables=()):
if kw is None:
kw = {}
return dict(
diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py
index 2576b4e35..05881571e 100644
--- a/pyramid/interfaces.py
+++ b/pyramid/interfaces.py
@@ -996,12 +996,13 @@ class IIntrospectable(Interface):
"""
class IActionInfo(Interface):
- filename = Attribute('filename as a string')
- lineno = Attribute('line number in file as an integer')
- function = Attribute('a string representing the function or method '
- 'that was executing')
- linerepr = Attribute('a string representing the call site '
- 'which caused the action to be executed')
+ filename = Attribute('filename of action-invoking code as a string')
+ lineno = Attribute('line number in file (as an integer) of action-invoking '
+ 'code')
+ function = Attribute('a string representing the module, function or method '
+ 'that enclosed the line which invoked the action')
+ linerepr = Attribute('a string representing the source code line '
+ 'which invoked the action')
# configuration phases: a lower phase number means the actions associated
# with this phase will be executed earlier than those with later phase
diff --git a/pyramid/tests/test_config/test_init.py b/pyramid/tests/test_config/test_init.py
index e80557096..86dace822 100644
--- a/pyramid/tests/test_config/test_init.py
+++ b/pyramid/tests/test_config/test_init.py
@@ -228,6 +228,12 @@ class ConfiguratorTests(unittest.TestCase):
request_iface=IRequest)
self.assertTrue(view.__wraps__ is exceptionresponse_view)
+ def test_ctor_with_introspector(self):
+ introspector = DummyIntrospector()
+ config = self._makeOne(introspector=introspector)
+ self.assertEqual(config.introspector, introspector)
+ self.assertEqual(config.registry.introspector, introspector)
+
def test_with_package_module(self):
from pyramid.tests.test_config import test_init
import pyramid.tests
@@ -637,6 +643,21 @@ pyramid.tests.test_config.dummy_include2""",
[('pyramid.tests.test_config.dummy_tween_factory',
dummy_tween_factory)])
+ def test_introspector_decorator(self):
+ inst = self._makeOne()
+ default = inst.introspector
+ self.failUnless(hasattr(default, 'add'))
+ self.assertEqual(inst.introspector, inst.registry.introspector)
+ introspector = DummyIntrospector()
+ inst.introspector = introspector
+ new = inst.introspector
+ self.failUnless(new is introspector)
+ self.assertEqual(inst.introspector, inst.registry.introspector)
+ del inst.introspector
+ default = inst.introspector
+ self.failIf(default is new)
+ self.failUnless(hasattr(default, 'add'))
+
def test_make_wsgi_app(self):
import pyramid.config
from pyramid.router import Router
@@ -740,6 +761,15 @@ pyramid.tests.test_config.dummy_include2""",
config = self._makeOne(autocommit=True)
self.assertEqual(config.action('discrim', kw={'a':1}), None)
+ def test_action_autocommit_with_introspectables(self):
+ from pyramid.config.util import ActionInfo
+ config = self._makeOne(autocommit=True)
+ intr = DummyIntrospectable()
+ config.action('discrim', introspectables=(intr,))
+ self.assertEqual(len(intr.registered), 1)
+ self.assertEqual(intr.registered[0][0], config.introspector)
+ self.assertEqual(intr.registered[0][1].__class__, ActionInfo)
+
def test_action_branching_nonautocommit_with_config_info(self):
config = self._makeOne(autocommit=False)
config.info = 'abc'
@@ -779,6 +809,18 @@ pyramid.tests.test_config.dummy_include2""",
'kw': {'a': 1},
'order': None})])
+ def test_action_branching_nonautocommit_with_introspectables(self):
+ config = self._makeOne(autocommit=False)
+ config.info = ''
+ config._ainfo = []
+ state = DummyActionState()
+ config.action_state = state
+ state.autocommit = False
+ intr = DummyIntrospectable()
+ config.action('discrim', introspectables=(intr,))
+ self.assertEqual(
+ state.actions[0][1]['introspectables'], (intr,))
+
def test_scan_integration(self):
from zope.interface import alsoProvides
from pyramid.interfaces import IRequest
@@ -1398,7 +1440,7 @@ class TestActionState(unittest.TestCase):
'callable': f,
'discriminator': 1,
'includepath': (),
- 'info': '',
+ 'info': None,
'introspectables': (),
'kw': {'x': 1},
'order': None}])
@@ -1409,7 +1451,7 @@ class TestActionState(unittest.TestCase):
'callable': f,
'discriminator': 1,
'includepath': (),
- 'info': '',
+ 'info': None,
'introspectables': (),
'kw': {'x': 1},
'order': None},
@@ -1418,7 +1460,7 @@ class TestActionState(unittest.TestCase):
'callable': None,
'discriminator': None,
'includepath': (),
- 'info': '',
+ 'info': None,
'introspectables': (),
'kw': {},
'order': None},])
@@ -1433,7 +1475,7 @@ class TestActionState(unittest.TestCase):
'callable': None,
'discriminator': None,
'includepath': ('abc',),
- 'info': '',
+ 'info': None,
'introspectables': (),
'kw': {},
'order': None}])
@@ -1476,20 +1518,36 @@ class TestActionState(unittest.TestCase):
'callable': None,
'discriminator': None,
'includepath': (),
- 'info': '',
+ 'info': None,
'introspectables': (),
'kw': {},
'order': 99999}])
+ def test_action_with_introspectables(self):
+ c = self._makeOne()
+ c.actions = []
+ intr = DummyIntrospectable()
+ c.action(None, introspectables=(intr,))
+ self.assertEqual(
+ c.actions,
+ [{'args': (),
+ 'callable': None,
+ 'discriminator': None,
+ 'includepath': (),
+ 'info': None,
+ 'introspectables': (intr,),
+ 'kw': {},
+ 'order': None}])
+
def test_processSpec(self):
c = self._makeOne()
self.assertTrue(c.processSpec('spec'))
self.assertFalse(c.processSpec('spec'))
- def test_execute_actions_simple(self):
+ def test_execute_actions_tuples(self):
output = []
def f(*a, **k):
- output.append(('f', a, k))
+ output.append((a, k))
c = self._makeOne()
c.actions = [
(1, f, (1,)),
@@ -1498,7 +1556,57 @@ class TestActionState(unittest.TestCase):
(None, None),
]
c.execute_actions()
- self.assertEqual(output, [('f', (1,), {}), ('f', (2,), {})])
+ self.assertEqual(output, [((1,), {}), ((2,), {})])
+
+ def test_execute_actions_dicts(self):
+ output = []
+ def f(*a, **k):
+ output.append((a, k))
+ c = self._makeOne()
+ c.actions = [
+ {'discriminator':1, 'callable':f, 'args':(1,), 'kw':{},
+ 'order':None, 'includepath':(), 'info':None,
+ 'introspectables':()},
+ {'discriminator':1, 'callable':f, 'args':(11,), 'kw':{},
+ 'includepath':('x',), 'order': None, 'info':None,
+ 'introspectables':()},
+ {'discriminator':2, 'callable':f, 'args':(2,), 'kw':{},
+ 'order':None, 'includepath':(), 'info':None,
+ 'introspectables':()},
+ {'discriminator':None, 'callable':None, 'args':(), 'kw':{},
+ 'order':None, 'includepath':(), 'info':None,
+ 'introspectables':()},
+ ]
+ c.execute_actions()
+ self.assertEqual(output, [((1,), {}), ((2,), {})])
+
+ def test_execute_actions_with_introspectables(self):
+ output = []
+ def f(*a, **k):
+ output.append((a, k))
+ c = self._makeOne()
+ intr = DummyIntrospectable()
+ c.actions = [
+ {'discriminator':1, 'callable':f, 'args':(1,), 'kw':{},
+ 'order':None, 'includepath':(), 'info':None,
+ 'introspectables':(intr,)},
+ ]
+ introspector = DummyIntrospector()
+ c.execute_actions(introspector=introspector)
+ self.assertEqual(output, [((1,), {})])
+ self.assertEqual(intr.registered, [(introspector, None)])
+
+ def test_execute_actions_with_introspectable_no_callable(self):
+ c = self._makeOne()
+ intr = DummyIntrospectable()
+ c.actions = [
+ {'discriminator':1, 'callable':None, 'args':(1,), 'kw':{},
+ 'order':None, 'includepath':(), 'info':None,
+ 'introspectables':(intr,)},
+ ]
+ introspector = DummyIntrospector()
+ c.execute_actions(introspector=introspector)
+ self.assertEqual(intr.registered, [(introspector, None)])
def test_execute_actions_error(self):
output = []
@@ -1521,7 +1629,7 @@ class Test_resolveConflicts(unittest.TestCase):
from pyramid.config import resolveConflicts
return resolveConflicts(actions)
- def test_it_success(self):
+ def test_it_success_tuples(self):
from pyramid.tests.test_config import dummyfactory as f
result = self._callFUT([
(None, f),
@@ -1534,7 +1642,68 @@ class Test_resolveConflicts(unittest.TestCase):
])
self.assertEqual(
result,
- [{'info': '',
+ [{'info': None,
+ 'args': (),
+ 'callable': f,
+ 'introspectables': (),
+ 'kw': {},
+ 'discriminator': None,
+ 'includepath': (),
+ 'order': 0},
+
+ {'info': 'first',
+ 'args': (1,),
+ 'callable': f,
+ 'introspectables': (),
+ 'kw': {},
+ 'discriminator': 1,
+ 'includepath': (),
+ 'order': 1},
+
+ {'info': None,
+ 'args': (3,),
+ 'callable': f,
+ 'introspectables': (),
+ 'kw': {},
+ 'discriminator': 3,
+ 'includepath': ('y',),
+ 'order': 5},
+
+ {'info': None,
+ 'args': (5,),
+ 'callable': f,
+ 'introspectables': (),
+ 'kw': {},
+ 'discriminator': None,
+ 'includepath': ('y',),
+ 'order': 6},
+
+ {'info': 'should be last',
+ 'args': (4,),
+ 'callable': f,
+ 'introspectables': (),
+ 'kw': {},
+ 'discriminator': 4,
+ 'includepath': ('y',),
+ 'order': 99999}
+ ]
+ )
+
+ def test_it_success_dicts(self):
+ from pyramid.tests.test_config import dummyfactory as f
+ from pyramid.config import expand_action
+ result = self._callFUT([
+ expand_action(None, f),
+ expand_action(1, f, (1,), {}, (), 'first'),
+ expand_action(1, f, (2,), {}, ('x',), 'second'),
+ expand_action(1, f, (3,), {}, ('y',), 'third'),
+ expand_action(4, f, (4,), {}, ('y',), 'should be last', 99999),
+ expand_action(3, f, (3,), {}, ('y',)),
+ expand_action(None, f, (5,), {}, ('y',)),
+ ])
+ self.assertEqual(
+ result,
+ [{'info': None,
'args': (),
'callable': f,
'introspectables': (),
@@ -1552,7 +1721,7 @@ class Test_resolveConflicts(unittest.TestCase):
'includepath': (),
'order': 1},
- {'info': '',
+ {'info': None,
'args': (3,),
'callable': f,
'introspectables': (),
@@ -1561,7 +1730,7 @@ class Test_resolveConflicts(unittest.TestCase):
'includepath': ('y',),
'order': 5},
- {'info': '',
+ {'info': None,
'args': (5,),
'callable': f,
'introspectables': (),
@@ -1700,3 +1869,15 @@ class DummyZCMLContext(object):
includepath = ()
info = ''
+class DummyIntrospector(object):
+ def __init__(self):
+ self.intrs = []
+ def add(self, intr):
+ self.intrs.append(intr)
+
+class DummyIntrospectable(object):
+ def __init__(self):
+ self.registered = []
+ def register(self, introspector, action_info):
+ self.registered.append((introspector, action_info))
+
diff --git a/pyramid/tests/test_config/test_util.py b/pyramid/tests/test_config/test_util.py
index bc7cf0a82..1225b3e21 100644
--- a/pyramid/tests/test_config/test_util.py
+++ b/pyramid/tests/test_config/test_util.py
@@ -312,6 +312,16 @@ class Test__make_predicates(unittest.TestCase):
hash2, _, __= self._callFUT(request_method='GET')
self.assertEqual(hash1, hash2)
+class TestActionInfo(unittest.TestCase):
+ def _makeOne(self, filename, lineno, function, linerepr):
+ from pyramid.config.util import ActionInfo
+ return ActionInfo(filename, lineno, function, linerepr)
+
+ def test___str__(self):
+ inst = self._makeOne('filename', 'lineno', 'function', 'linerepr')
+ self.assertEqual(str(inst),
+ "Line lineno of file filename in function: 'linerepr'")
+
class DummyCustomPredicate(object):
def __init__(self):
self.__text__ = 'custom predicate'
diff --git a/pyramid/tests/test_util.py b/pyramid/tests/test_util.py
index d010e6653..61e372417 100644
--- a/pyramid/tests/test_util.py
+++ b/pyramid/tests/test_util.py
@@ -279,9 +279,9 @@ class Test_object_description(unittest.TestCase):
self.assertEqual(self._callFUT(('a', 'b')), "('a', 'b')")
def test_set(self):
- if PY3:
+ if PY3: # pragma: no cover
self.assertEqual(self._callFUT(set(['a'])), "{'a'}")
- else:
+ else: # pragma: no cover
self.assertEqual(self._callFUT(set(['a'])), "set(['a'])")
def test_list(self):