From e4c0570d5c67ddf0ad9502169b59475ba0784d82 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 18 Oct 2018 01:27:04 -0500 Subject: move action-related code into pyramid.config.actions --- tests/test_config/test_actions.py | 1055 +++++++++++++++++++++++++++++++++++++ tests/test_config/test_init.py | 1033 ------------------------------------ tests/test_config/test_testing.py | 2 +- 3 files changed, 1056 insertions(+), 1034 deletions(-) create mode 100644 tests/test_config/test_actions.py (limited to 'tests') diff --git a/tests/test_config/test_actions.py b/tests/test_config/test_actions.py new file mode 100644 index 000000000..ba8b8c124 --- /dev/null +++ b/tests/test_config/test_actions.py @@ -0,0 +1,1055 @@ +import unittest + +from pyramid.exceptions import ConfigurationConflictError +from pyramid.exceptions import ConfigurationExecutionError + +from pyramid.interfaces import IRequest + + +class ConfiguratorTests(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + + config = Configurator(*arg, **kw) + return config + + def _getViewCallable( + self, + config, + ctx_iface=None, + request_iface=None, + name='', + exception_view=False, + ): + from zope.interface import Interface + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + + if exception_view: # pragma: no cover + classifier = IExceptionViewClassifier + else: + classifier = IViewClassifier + if ctx_iface is None: + ctx_iface = Interface + if request_iface is None: + request_iface = IRequest + return config.registry.adapters.lookup( + (classifier, request_iface, ctx_iface), + IView, + name=name, + default=None, + ) + + def test_action_branching_kw_is_None(self): + config = self._makeOne(autocommit=True) + self.assertEqual(config.action('discrim'), None) + + def test_action_branching_kw_is_not_None(self): + 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_autocommit_with_introspectables_introspection_off(self): + config = self._makeOne(autocommit=True) + config.introspection = False + intr = DummyIntrospectable() + config.action('discrim', introspectables=(intr,)) + self.assertEqual(len(intr.registered), 0) + + def test_action_branching_nonautocommit_with_config_info(self): + config = self._makeOne(autocommit=False) + config.info = 'abc' + state = DummyActionState() + state.autocommit = False + config.action_state = state + config.action('discrim', kw={'a': 1}) + self.assertEqual( + state.actions, + [ + ( + (), + { + 'args': (), + 'callable': None, + 'discriminator': 'discrim', + 'includepath': (), + 'info': 'abc', + 'introspectables': (), + 'kw': {'a': 1}, + 'order': 0, + }, + ) + ], + ) + + def test_action_branching_nonautocommit_without_config_info(self): + config = self._makeOne(autocommit=False) + config.info = '' + config._ainfo = ['z'] + state = DummyActionState() + config.action_state = state + state.autocommit = False + config.action('discrim', kw={'a': 1}) + self.assertEqual( + state.actions, + [ + ( + (), + { + 'args': (), + 'callable': None, + 'discriminator': 'discrim', + 'includepath': (), + 'info': 'z', + 'introspectables': (), + 'kw': {'a': 1}, + 'order': 0, + }, + ) + ], + ) + + 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_action_nonautocommit_with_introspectables_introspection_off(self): + config = self._makeOne(autocommit=False) + config.info = '' + config._ainfo = [] + config.introspection = False + state = DummyActionState() + config.action_state = state + state.autocommit = False + intr = DummyIntrospectable() + config.action('discrim', introspectables=(intr,)) + self.assertEqual(state.actions[0][1]['introspectables'], ()) + + def test_commit_conflict_simple(self): + config = self._makeOne() + + def view1(request): # pragma: no cover + pass + + def view2(request): # pragma: no cover + pass + + config.add_view(view1) + config.add_view(view2) + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_commit_conflict_resolved_with_include(self): + config = self._makeOne() + + def view1(request): # pragma: no cover + pass + + def view2(request): # pragma: no cover + pass + + def includeme(config): + config.add_view(view2) + + config.add_view(view1) + config.include(includeme) + config.commit() + registeredview = self._getViewCallable(config) + self.assertEqual(registeredview.__name__, 'view1') + + def test_commit_conflict_with_two_includes(self): + config = self._makeOne() + + def view1(request): # pragma: no cover + pass + + def view2(request): # pragma: no cover + pass + + def includeme1(config): + config.add_view(view1) + + def includeme2(config): + config.add_view(view2) + + config.include(includeme1) + config.include(includeme2) + try: + config.commit() + except ConfigurationConflictError as why: + c1, c2 = _conflictFunctions(why) + self.assertEqual(c1, 'includeme1') + self.assertEqual(c2, 'includeme2') + else: # pragma: no cover + raise AssertionError + + def test_commit_conflict_resolved_with_two_includes_and_local(self): + config = self._makeOne() + + def view1(request): # pragma: no cover + pass + + def view2(request): # pragma: no cover + pass + + def view3(request): # pragma: no cover + pass + + def includeme1(config): + config.add_view(view1) + + def includeme2(config): + config.add_view(view2) + + config.include(includeme1) + config.include(includeme2) + config.add_view(view3) + config.commit() + registeredview = self._getViewCallable(config) + self.assertEqual(registeredview.__name__, 'view3') + + def test_autocommit_no_conflicts(self): + from pyramid.renderers import null_renderer + + config = self._makeOne(autocommit=True) + + def view1(request): # pragma: no cover + pass + + def view2(request): # pragma: no cover + pass + + def view3(request): # pragma: no cover + pass + + config.add_view(view1, renderer=null_renderer) + config.add_view(view2, renderer=null_renderer) + config.add_view(view3, renderer=null_renderer) + config.commit() + registeredview = self._getViewCallable(config) + self.assertEqual(registeredview.__name__, 'view3') + + def test_conflict_set_notfound_view(self): + config = self._makeOne() + + def view1(request): # pragma: no cover + pass + + def view2(request): # pragma: no cover + pass + + config.set_notfound_view(view1) + config.set_notfound_view(view2) + try: + config.commit() + except ConfigurationConflictError as why: + c1, c2 = _conflictFunctions(why) + self.assertEqual(c1, 'test_conflict_set_notfound_view') + self.assertEqual(c2, 'test_conflict_set_notfound_view') + else: # pragma: no cover + raise AssertionError + + def test_conflict_set_forbidden_view(self): + config = self._makeOne() + + def view1(request): # pragma: no cover + pass + + def view2(request): # pragma: no cover + pass + + config.set_forbidden_view(view1) + config.set_forbidden_view(view2) + try: + config.commit() + except ConfigurationConflictError as why: + c1, c2 = _conflictFunctions(why) + self.assertEqual(c1, 'test_conflict_set_forbidden_view') + self.assertEqual(c2, 'test_conflict_set_forbidden_view') + else: # pragma: no cover + raise AssertionError + + +class TestActionState(unittest.TestCase): + def _makeOne(self): + from pyramid.config.actions import ActionState + + return ActionState() + + def test_it(self): + c = self._makeOne() + self.assertEqual(c.actions, []) + + def test_action_simple(self): + from . import dummyfactory as f + + c = self._makeOne() + c.actions = [] + c.action(1, f, (1,), {'x': 1}) + self.assertEqual( + c.actions, + [ + { + 'args': (1,), + 'callable': f, + 'discriminator': 1, + 'includepath': (), + 'info': None, + 'introspectables': (), + 'kw': {'x': 1}, + 'order': 0, + } + ], + ) + c.action(None) + self.assertEqual( + c.actions, + [ + { + 'args': (1,), + 'callable': f, + 'discriminator': 1, + 'includepath': (), + 'info': None, + 'introspectables': (), + 'kw': {'x': 1}, + 'order': 0, + }, + { + 'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': (), + 'info': None, + 'introspectables': (), + 'kw': {}, + 'order': 0, + }, + ], + ) + + def test_action_with_includepath(self): + c = self._makeOne() + c.actions = [] + c.action(None, includepath=('abc',)) + self.assertEqual( + c.actions, + [ + { + 'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': ('abc',), + 'info': None, + 'introspectables': (), + 'kw': {}, + 'order': 0, + } + ], + ) + + def test_action_with_info(self): + c = self._makeOne() + c.action(None, info='abc') + self.assertEqual( + c.actions, + [ + { + 'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': (), + 'info': 'abc', + 'introspectables': (), + 'kw': {}, + 'order': 0, + } + ], + ) + + def test_action_with_includepath_and_info(self): + c = self._makeOne() + c.action(None, includepath=('spec',), info='bleh') + self.assertEqual( + c.actions, + [ + { + 'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': ('spec',), + 'info': 'bleh', + 'introspectables': (), + 'kw': {}, + 'order': 0, + } + ], + ) + + def test_action_with_order(self): + c = self._makeOne() + c.actions = [] + c.action(None, order=99999) + self.assertEqual( + c.actions, + [ + { + 'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': (), + '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': 0, + } + ], + ) + + def test_processSpec(self): + c = self._makeOne() + self.assertTrue(c.processSpec('spec')) + self.assertFalse(c.processSpec('spec')) + + def test_execute_actions_tuples(self): + output = [] + + def f(*a, **k): + output.append((a, k)) + + c = self._makeOne() + c.actions = [ + (1, f, (1,)), + (1, f, (11,), {}, ('x',)), + (2, f, (2,)), + (None, None), + ] + c.execute_actions() + 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': 0, + 'includepath': (), + 'info': None, + 'introspectables': (), + }, + { + 'discriminator': 1, + 'callable': f, + 'args': (11,), + 'kw': {}, + 'includepath': ('x',), + 'order': 0, + 'info': None, + 'introspectables': (), + }, + { + 'discriminator': 2, + 'callable': f, + 'args': (2,), + 'kw': {}, + 'order': 0, + 'includepath': (), + 'info': None, + 'introspectables': (), + }, + { + 'discriminator': None, + 'callable': None, + 'args': (), + 'kw': {}, + 'order': 0, + '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': 0, + 'includepath': (), + 'info': None, + 'introspectables': (intr,), + } + ] + introspector = object() + 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': 0, + 'includepath': (), + 'info': None, + 'introspectables': (intr,), + } + ] + introspector = object() + c.execute_actions(introspector=introspector) + self.assertEqual(intr.registered, [(introspector, None)]) + + def test_execute_actions_error(self): + output = [] + + def f(*a, **k): + output.append(('f', a, k)) + + def bad(): + raise NotImplementedError + + c = self._makeOne() + c.actions = [ + (1, f, (1,)), + (1, f, (11,), {}, ('x',)), + (2, f, (2,)), + (3, bad, (), {}, (), 'oops'), + ] + self.assertRaises(ConfigurationExecutionError, c.execute_actions) + self.assertEqual(output, [('f', (1,), {}), ('f', (2,), {})]) + + def test_reentrant_action(self): + output = [] + c = self._makeOne() + + def f(*a, **k): + output.append(('f', a, k)) + c.actions.append((3, g, (8,), {})) + + def g(*a, **k): + output.append(('g', a, k)) + + c.actions = [(1, f, (1,))] + c.execute_actions() + self.assertEqual(output, [('f', (1,), {}), ('g', (8,), {})]) + + def test_reentrant_action_with_deferred_discriminator(self): + # see https://github.com/Pylons/pyramid/issues/2697 + from pyramid.registry import Deferred + + output = [] + c = self._makeOne() + + def f(*a, **k): + output.append(('f', a, k)) + c.actions.append((4, g, (4,), {}, (), None, 2)) + + def g(*a, **k): + output.append(('g', a, k)) + + def h(*a, **k): + output.append(('h', a, k)) + + def discrim(): + self.assertEqual(output, [('f', (1,), {}), ('g', (2,), {})]) + return 3 + + d = Deferred(discrim) + c.actions = [ + (d, h, (3,), {}, (), None, 1), # order 1 + (1, f, (1,)), # order 0 + (2, g, (2,)), # order 0 + ] + c.execute_actions() + self.assertEqual( + output, + [ + ('f', (1,), {}), + ('g', (2,), {}), + ('h', (3,), {}), + ('g', (4,), {}), + ], + ) + + def test_reentrant_action_error(self): + from pyramid.exceptions import ConfigurationError + + c = self._makeOne() + + def f(*a, **k): + c.actions.append((3, g, (8,), {}, (), None, -1)) + + def g(*a, **k): # pragma: no cover + pass + + c.actions = [(1, f, (1,))] + self.assertRaises(ConfigurationError, c.execute_actions) + + def test_reentrant_action_without_clear(self): + c = self._makeOne() + + def f(*a, **k): + c.actions.append((3, g, (8,))) + + def g(*a, **k): + pass + + c.actions = [(1, f, (1,))] + c.execute_actions(clear=False) + self.assertEqual(c.actions, [(1, f, (1,)), (3, g, (8,))]) + + def test_executing_conflicting_action_across_orders(self): + from pyramid.exceptions import ConfigurationConflictError + + c = self._makeOne() + + def f(*a, **k): + pass + + def g(*a, **k): # pragma: no cover + pass + + c.actions = [(1, f, (1,), {}, (), None, -1), (1, g, (2,))] + self.assertRaises(ConfigurationConflictError, c.execute_actions) + + def test_executing_conflicting_action_across_reentrant_orders(self): + from pyramid.exceptions import ConfigurationConflictError + + c = self._makeOne() + + def f(*a, **k): + c.actions.append((1, g, (8,))) + + def g(*a, **k): # pragma: no cover + pass + + c.actions = [(1, f, (1,), {}, (), None, -1)] + self.assertRaises(ConfigurationConflictError, c.execute_actions) + + +class Test_reentrant_action_functional(unittest.TestCase): + def _makeConfigurator(self, *arg, **kw): + from pyramid.config import Configurator + + config = Configurator(*arg, **kw) + return config + + def test_functional(self): + def add_auto_route(config, name, view): + def register(): + config.add_view(route_name=name, view=view) + config.add_route(name, '/' + name) + + config.action(('auto route', name), register, order=-30) + + config = self._makeConfigurator() + config.add_directive('add_auto_route', add_auto_route) + + def my_view(request): # pragma: no cover + return request.response + + config.add_auto_route('foo', my_view) + config.commit() + from pyramid.interfaces import IRoutesMapper + + mapper = config.registry.getUtility(IRoutesMapper) + routes = mapper.get_routes() + route = routes[0] + self.assertEqual(len(routes), 1) + self.assertEqual(route.name, 'foo') + self.assertEqual(route.path, '/foo') + + def test_deferred_discriminator(self): + # see https://github.com/Pylons/pyramid/issues/2697 + from pyramid.config import PHASE0_CONFIG + + config = self._makeConfigurator() + + def deriver(view, info): + return view + + deriver.options = ('foo',) + config.add_view_deriver(deriver, 'foo_view') + # add_view uses a deferred discriminator and will fail if executed + # prior to add_view_deriver executing its action + config.add_view(lambda r: r.response, name='', foo=1) + + def dummy_action(): + # trigger a re-entrant action + config.action(None, lambda: None) + + config.action(None, dummy_action, order=PHASE0_CONFIG) + config.commit() + + +class Test_resolveConflicts(unittest.TestCase): + def _callFUT(self, actions): + from pyramid.config.actions import resolveConflicts + + return resolveConflicts(actions) + + def test_it_success_tuples(self): + from . import dummyfactory as f + + result = self._callFUT( + [ + (None, f), + (1, f, (1,), {}, (), 'first'), + (1, f, (2,), {}, ('x',), 'second'), + (1, f, (3,), {}, ('y',), 'third'), + (4, f, (4,), {}, ('y',), 'should be last', 99999), + (3, f, (3,), {}, ('y',)), + (None, f, (5,), {}, ('y',)), + ] + ) + result = list(result) + self.assertEqual( + result, + [ + { + 'info': None, + 'args': (), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': (), + 'order': 0, + }, + { + 'info': 'first', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 1, + 'includepath': (), + 'order': 0, + }, + { + 'info': None, + 'args': (3,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 3, + 'includepath': ('y',), + 'order': 0, + }, + { + 'info': None, + 'args': (5,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': ('y',), + 'order': 0, + }, + { + 'info': 'should be last', + 'args': (4,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 4, + 'includepath': ('y',), + 'order': 99999, + }, + ], + ) + + def test_it_success_dicts(self): + from . import dummyfactory as f + + result = self._callFUT( + [ + (None, f), + (1, f, (1,), {}, (), 'first'), + (1, f, (2,), {}, ('x',), 'second'), + (1, f, (3,), {}, ('y',), 'third'), + (4, f, (4,), {}, ('y',), 'should be last', 99999), + (3, f, (3,), {}, ('y',)), + (None, f, (5,), {}, ('y',)), + ] + ) + result = list(result) + self.assertEqual( + result, + [ + { + 'info': None, + 'args': (), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': (), + 'order': 0, + }, + { + 'info': 'first', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 1, + 'includepath': (), + 'order': 0, + }, + { + 'info': None, + 'args': (3,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 3, + 'includepath': ('y',), + 'order': 0, + }, + { + 'info': None, + 'args': (5,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': ('y',), + 'order': 0, + }, + { + 'info': 'should be last', + 'args': (4,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 4, + 'includepath': ('y',), + 'order': 99999, + }, + ], + ) + + def test_it_conflict(self): + from . import dummyfactory as f + + result = self._callFUT( + [ + (None, f), + (1, f, (2,), {}, ('x',), 'eek'), # will conflict + (1, f, (3,), {}, ('y',), 'ack'), # will conflict + (4, f, (4,), {}, ('y',)), + (3, f, (3,), {}, ('y',)), + (None, f, (5,), {}, ('y',)), + ] + ) + self.assertRaises(ConfigurationConflictError, list, result) + + def test_it_with_actions_grouped_by_order(self): + from . import dummyfactory as f + + result = self._callFUT( + [ + (None, f), # X + (1, f, (1,), {}, (), 'third', 10), # X + (1, f, (2,), {}, ('x',), 'fourth', 10), + (1, f, (3,), {}, ('y',), 'fifth', 10), + (2, f, (1,), {}, (), 'sixth', 10), # X + (3, f, (1,), {}, (), 'seventh', 10), # X + (5, f, (4,), {}, ('y',), 'eighth', 99999), # X + (4, f, (3,), {}, (), 'first', 5), # X + (4, f, (5,), {}, ('y',), 'second', 5), + ] + ) + result = list(result) + self.assertEqual(len(result), 6) + # resolved actions should be grouped by (order, i) + self.assertEqual( + result, + [ + { + 'info': None, + 'args': (), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': (), + 'order': 0, + }, + { + 'info': 'first', + 'args': (3,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 4, + 'includepath': (), + 'order': 5, + }, + { + 'info': 'third', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 1, + 'includepath': (), + 'order': 10, + }, + { + 'info': 'sixth', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 2, + 'includepath': (), + 'order': 10, + }, + { + 'info': 'seventh', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 3, + 'includepath': (), + 'order': 10, + }, + { + 'info': 'eighth', + 'args': (4,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 5, + 'includepath': ('y',), + 'order': 99999, + }, + ], + ) + + def test_override_success_across_orders(self): + from . import dummyfactory as f + + result = self._callFUT( + [ + (1, f, (2,), {}, ('x',), 'eek', 0), + (1, f, (3,), {}, ('x', 'y'), 'ack', 10), + ] + ) + result = list(result) + self.assertEqual( + result, + [ + { + 'info': 'eek', + 'args': (2,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 1, + 'includepath': ('x',), + 'order': 0, + } + ], + ) + + def test_conflicts_across_orders(self): + from . import dummyfactory as f + + result = self._callFUT( + [ + (1, f, (2,), {}, ('x', 'y'), 'eek', 0), + (1, f, (3,), {}, ('x'), 'ack', 10), + ] + ) + self.assertRaises(ConfigurationConflictError, list, result) + + +def _conflictFunctions(e): + conflicts = e._conflicts.values() + for conflict in conflicts: + for confinst in conflict: + yield confinst.function + + +class DummyActionState(object): + autocommit = False + info = '' + + def __init__(self): + self.actions = [] + + def action(self, *arg, **kw): + self.actions.append((arg, kw)) + + +class DummyIntrospectable(object): + def __init__(self): + self.registered = [] + + def register(self, introspector, action_info): + self.registered.append((introspector, action_info)) diff --git a/tests/test_config/test_init.py b/tests/test_config/test_init.py index 2c92b60fb..8216b5557 100644 --- a/tests/test_config/test_init.py +++ b/tests/test_config/test_init.py @@ -1,7 +1,5 @@ import os import unittest -from zope.interface import Interface -from zope.interface import implementer from pyramid.compat import im_func from pyramid.testing import skip_on @@ -10,7 +8,6 @@ from . import dummy_tween_factory from . import dummy_include from . import dummy_extend from . import dummy_extend2 -from . import IDummy from . import DummyContext from pyramid.exceptions import ConfigurationExecutionError @@ -35,7 +32,6 @@ class ConfiguratorTests(unittest.TestCase): exception_view=False, ): from zope.interface import Interface - from pyramid.interfaces import IRequest from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IExceptionViewClassifier @@ -299,7 +295,6 @@ class ConfiguratorTests(unittest.TestCase): def test_ctor_httpexception_view_default(self): from pyramid.interfaces import IExceptionResponse from pyramid.httpexceptions import default_exceptionresponse_view - from pyramid.interfaces import IRequest config = self._makeOne() view = self._getViewCallable( @@ -309,7 +304,6 @@ class ConfiguratorTests(unittest.TestCase): def test_ctor_exceptionresponse_view_None(self): from pyramid.interfaces import IExceptionResponse - from pyramid.interfaces import IRequest config = self._makeOne(exceptionresponse_view=None) view = self._getViewCallable( @@ -319,7 +313,6 @@ class ConfiguratorTests(unittest.TestCase): def test_ctor_exceptionresponse_view_custom(self): from pyramid.interfaces import IExceptionResponse - from pyramid.interfaces import IRequest def exceptionresponse_view(context, request): # pragma: no cover pass @@ -548,7 +541,6 @@ class ConfiguratorTests(unittest.TestCase): def test_setup_registry_explicit_notfound_trumps_iexceptionresponse(self): from pyramid.renderers import null_renderer from zope.interface import implementedBy - from pyramid.interfaces import IRequest from pyramid.httpexceptions import HTTPNotFound from pyramid.registry import Registry @@ -975,110 +967,8 @@ test_config.dummy_include2""" config.include(include) self.assertTrue(stack[0] is config.registry) - def test_action_branching_kw_is_None(self): - config = self._makeOne(autocommit=True) - self.assertEqual(config.action('discrim'), None) - - def test_action_branching_kw_is_not_None(self): - 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_autocommit_with_introspectables_introspection_off(self): - config = self._makeOne(autocommit=True) - config.introspection = False - intr = DummyIntrospectable() - config.action('discrim', introspectables=(intr,)) - self.assertEqual(len(intr.registered), 0) - - def test_action_branching_nonautocommit_with_config_info(self): - config = self._makeOne(autocommit=False) - config.info = 'abc' - state = DummyActionState() - state.autocommit = False - config.action_state = state - config.action('discrim', kw={'a': 1}) - self.assertEqual( - state.actions, - [ - ( - (), - { - 'args': (), - 'callable': None, - 'discriminator': 'discrim', - 'includepath': (), - 'info': 'abc', - 'introspectables': (), - 'kw': {'a': 1}, - 'order': 0, - }, - ) - ], - ) - - def test_action_branching_nonautocommit_without_config_info(self): - config = self._makeOne(autocommit=False) - config.info = '' - config._ainfo = ['z'] - state = DummyActionState() - config.action_state = state - state.autocommit = False - config.action('discrim', kw={'a': 1}) - self.assertEqual( - state.actions, - [ - ( - (), - { - 'args': (), - 'callable': None, - 'discriminator': 'discrim', - 'includepath': (), - 'info': 'z', - 'introspectables': (), - 'kw': {'a': 1}, - 'order': 0, - }, - ) - ], - ) - - 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_action_nonautocommit_with_introspectables_introspection_off(self): - config = self._makeOne(autocommit=False) - config.info = '' - config._ainfo = [] - config.introspection = False - state = DummyActionState() - config.action_state = state - state.autocommit = False - intr = DummyIntrospectable() - config.action('discrim', introspectables=(intr,)) - self.assertEqual(state.actions[0][1]['introspectables'], ()) - def test_scan_integration(self): from zope.interface import alsoProvides - from pyramid.interfaces import IRequest from pyramid.view import render_view_to_response import tests.test_config.pkgs.scannable as package @@ -1185,7 +1075,6 @@ test_config.dummy_include2""" def test_scan_integration_with_ignore(self): from zope.interface import alsoProvides - from pyramid.interfaces import IRequest from pyramid.view import render_view_to_response import tests.test_config.pkgs.scannable as package @@ -1207,7 +1096,6 @@ test_config.dummy_include2""" def test_scan_integration_dottedname_package(self): from zope.interface import alsoProvides - from pyramid.interfaces import IRequest from pyramid.view import render_view_to_response config = self._makeOne(autocommit=True) @@ -1306,149 +1194,6 @@ test_config.dummy_include2""" finally: getSiteManager.reset() - def test_commit_conflict_simple(self): - config = self._makeOne() - - def view1(request): # pragma: no cover - pass - - def view2(request): # pragma: no cover - pass - - config.add_view(view1) - config.add_view(view2) - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_commit_conflict_resolved_with_include(self): - config = self._makeOne() - - def view1(request): # pragma: no cover - pass - - def view2(request): # pragma: no cover - pass - - def includeme(config): - config.add_view(view2) - - config.add_view(view1) - config.include(includeme) - config.commit() - registeredview = self._getViewCallable(config) - self.assertEqual(registeredview.__name__, 'view1') - - def test_commit_conflict_with_two_includes(self): - config = self._makeOne() - - def view1(request): # pragma: no cover - pass - - def view2(request): # pragma: no cover - pass - - def includeme1(config): - config.add_view(view1) - - def includeme2(config): - config.add_view(view2) - - config.include(includeme1) - config.include(includeme2) - try: - config.commit() - except ConfigurationConflictError as why: - c1, c2 = _conflictFunctions(why) - self.assertEqual(c1, 'includeme1') - self.assertEqual(c2, 'includeme2') - else: # pragma: no cover - raise AssertionError - - def test_commit_conflict_resolved_with_two_includes_and_local(self): - config = self._makeOne() - - def view1(request): # pragma: no cover - pass - - def view2(request): # pragma: no cover - pass - - def view3(request): # pragma: no cover - pass - - def includeme1(config): - config.add_view(view1) - - def includeme2(config): - config.add_view(view2) - - config.include(includeme1) - config.include(includeme2) - config.add_view(view3) - config.commit() - registeredview = self._getViewCallable(config) - self.assertEqual(registeredview.__name__, 'view3') - - def test_autocommit_no_conflicts(self): - from pyramid.renderers import null_renderer - - config = self._makeOne(autocommit=True) - - def view1(request): # pragma: no cover - pass - - def view2(request): # pragma: no cover - pass - - def view3(request): # pragma: no cover - pass - - config.add_view(view1, renderer=null_renderer) - config.add_view(view2, renderer=null_renderer) - config.add_view(view3, renderer=null_renderer) - config.commit() - registeredview = self._getViewCallable(config) - self.assertEqual(registeredview.__name__, 'view3') - - def test_conflict_set_notfound_view(self): - config = self._makeOne() - - def view1(request): # pragma: no cover - pass - - def view2(request): # pragma: no cover - pass - - config.set_notfound_view(view1) - config.set_notfound_view(view2) - try: - config.commit() - except ConfigurationConflictError as why: - c1, c2 = _conflictFunctions(why) - self.assertEqual(c1, 'test_conflict_set_notfound_view') - self.assertEqual(c2, 'test_conflict_set_notfound_view') - else: # pragma: no cover - raise AssertionError - - def test_conflict_set_forbidden_view(self): - config = self._makeOne() - - def view1(request): # pragma: no cover - pass - - def view2(request): # pragma: no cover - pass - - config.set_forbidden_view(view1) - config.set_forbidden_view(view2) - try: - config.commit() - except ConfigurationConflictError as why: - c1, c2 = _conflictFunctions(why) - self.assertEqual(c1, 'test_conflict_set_forbidden_view') - self.assertEqual(c2, 'test_conflict_set_forbidden_view') - else: # pragma: no cover - raise AssertionError - def test___getattr__missing_when_directives_exist(self): config = self._makeOne() directives = {} @@ -1624,749 +1369,6 @@ class TestConfigurator__add_predicate(unittest.TestCase): ) -class TestActionState(unittest.TestCase): - def _makeOne(self): - from pyramid.config import ActionState - - return ActionState() - - def test_it(self): - c = self._makeOne() - self.assertEqual(c.actions, []) - - def test_action_simple(self): - from . import dummyfactory as f - - c = self._makeOne() - c.actions = [] - c.action(1, f, (1,), {'x': 1}) - self.assertEqual( - c.actions, - [ - { - 'args': (1,), - 'callable': f, - 'discriminator': 1, - 'includepath': (), - 'info': None, - 'introspectables': (), - 'kw': {'x': 1}, - 'order': 0, - } - ], - ) - c.action(None) - self.assertEqual( - c.actions, - [ - { - 'args': (1,), - 'callable': f, - 'discriminator': 1, - 'includepath': (), - 'info': None, - 'introspectables': (), - 'kw': {'x': 1}, - 'order': 0, - }, - { - 'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': (), - 'info': None, - 'introspectables': (), - 'kw': {}, - 'order': 0, - }, - ], - ) - - def test_action_with_includepath(self): - c = self._makeOne() - c.actions = [] - c.action(None, includepath=('abc',)) - self.assertEqual( - c.actions, - [ - { - 'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': ('abc',), - 'info': None, - 'introspectables': (), - 'kw': {}, - 'order': 0, - } - ], - ) - - def test_action_with_info(self): - c = self._makeOne() - c.action(None, info='abc') - self.assertEqual( - c.actions, - [ - { - 'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': (), - 'info': 'abc', - 'introspectables': (), - 'kw': {}, - 'order': 0, - } - ], - ) - - def test_action_with_includepath_and_info(self): - c = self._makeOne() - c.action(None, includepath=('spec',), info='bleh') - self.assertEqual( - c.actions, - [ - { - 'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': ('spec',), - 'info': 'bleh', - 'introspectables': (), - 'kw': {}, - 'order': 0, - } - ], - ) - - def test_action_with_order(self): - c = self._makeOne() - c.actions = [] - c.action(None, order=99999) - self.assertEqual( - c.actions, - [ - { - 'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': (), - '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': 0, - } - ], - ) - - def test_processSpec(self): - c = self._makeOne() - self.assertTrue(c.processSpec('spec')) - self.assertFalse(c.processSpec('spec')) - - def test_execute_actions_tuples(self): - output = [] - - def f(*a, **k): - output.append((a, k)) - - c = self._makeOne() - c.actions = [ - (1, f, (1,)), - (1, f, (11,), {}, ('x',)), - (2, f, (2,)), - (None, None), - ] - c.execute_actions() - 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': 0, - 'includepath': (), - 'info': None, - 'introspectables': (), - }, - { - 'discriminator': 1, - 'callable': f, - 'args': (11,), - 'kw': {}, - 'includepath': ('x',), - 'order': 0, - 'info': None, - 'introspectables': (), - }, - { - 'discriminator': 2, - 'callable': f, - 'args': (2,), - 'kw': {}, - 'order': 0, - 'includepath': (), - 'info': None, - 'introspectables': (), - }, - { - 'discriminator': None, - 'callable': None, - 'args': (), - 'kw': {}, - 'order': 0, - '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': 0, - 'includepath': (), - 'info': None, - 'introspectables': (intr,), - } - ] - introspector = object() - 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': 0, - 'includepath': (), - 'info': None, - 'introspectables': (intr,), - } - ] - introspector = object() - c.execute_actions(introspector=introspector) - self.assertEqual(intr.registered, [(introspector, None)]) - - def test_execute_actions_error(self): - output = [] - - def f(*a, **k): - output.append(('f', a, k)) - - def bad(): - raise NotImplementedError - - c = self._makeOne() - c.actions = [ - (1, f, (1,)), - (1, f, (11,), {}, ('x',)), - (2, f, (2,)), - (3, bad, (), {}, (), 'oops'), - ] - self.assertRaises(ConfigurationExecutionError, c.execute_actions) - self.assertEqual(output, [('f', (1,), {}), ('f', (2,), {})]) - - def test_reentrant_action(self): - output = [] - c = self._makeOne() - - def f(*a, **k): - output.append(('f', a, k)) - c.actions.append((3, g, (8,), {})) - - def g(*a, **k): - output.append(('g', a, k)) - - c.actions = [(1, f, (1,))] - c.execute_actions() - self.assertEqual(output, [('f', (1,), {}), ('g', (8,), {})]) - - def test_reentrant_action_with_deferred_discriminator(self): - # see https://github.com/Pylons/pyramid/issues/2697 - from pyramid.registry import Deferred - - output = [] - c = self._makeOne() - - def f(*a, **k): - output.append(('f', a, k)) - c.actions.append((4, g, (4,), {}, (), None, 2)) - - def g(*a, **k): - output.append(('g', a, k)) - - def h(*a, **k): - output.append(('h', a, k)) - - def discrim(): - self.assertEqual(output, [('f', (1,), {}), ('g', (2,), {})]) - return 3 - - d = Deferred(discrim) - c.actions = [ - (d, h, (3,), {}, (), None, 1), # order 1 - (1, f, (1,)), # order 0 - (2, g, (2,)), # order 0 - ] - c.execute_actions() - self.assertEqual( - output, - [ - ('f', (1,), {}), - ('g', (2,), {}), - ('h', (3,), {}), - ('g', (4,), {}), - ], - ) - - def test_reentrant_action_error(self): - from pyramid.exceptions import ConfigurationError - - c = self._makeOne() - - def f(*a, **k): - c.actions.append((3, g, (8,), {}, (), None, -1)) - - def g(*a, **k): # pragma: no cover - pass - - c.actions = [(1, f, (1,))] - self.assertRaises(ConfigurationError, c.execute_actions) - - def test_reentrant_action_without_clear(self): - c = self._makeOne() - - def f(*a, **k): - c.actions.append((3, g, (8,))) - - def g(*a, **k): - pass - - c.actions = [(1, f, (1,))] - c.execute_actions(clear=False) - self.assertEqual(c.actions, [(1, f, (1,)), (3, g, (8,))]) - - def test_executing_conflicting_action_across_orders(self): - from pyramid.exceptions import ConfigurationConflictError - - c = self._makeOne() - - def f(*a, **k): - pass - - def g(*a, **k): # pragma: no cover - pass - - c.actions = [(1, f, (1,), {}, (), None, -1), (1, g, (2,))] - self.assertRaises(ConfigurationConflictError, c.execute_actions) - - def test_executing_conflicting_action_across_reentrant_orders(self): - from pyramid.exceptions import ConfigurationConflictError - - c = self._makeOne() - - def f(*a, **k): - c.actions.append((1, g, (8,))) - - def g(*a, **k): # pragma: no cover - pass - - c.actions = [(1, f, (1,), {}, (), None, -1)] - self.assertRaises(ConfigurationConflictError, c.execute_actions) - - -class Test_reentrant_action_functional(unittest.TestCase): - def _makeConfigurator(self, *arg, **kw): - from pyramid.config import Configurator - - config = Configurator(*arg, **kw) - return config - - def test_functional(self): - def add_auto_route(config, name, view): - def register(): - config.add_view(route_name=name, view=view) - config.add_route(name, '/' + name) - - config.action(('auto route', name), register, order=-30) - - config = self._makeConfigurator() - config.add_directive('add_auto_route', add_auto_route) - - def my_view(request): # pragma: no cover - return request.response - - config.add_auto_route('foo', my_view) - config.commit() - from pyramid.interfaces import IRoutesMapper - - mapper = config.registry.getUtility(IRoutesMapper) - routes = mapper.get_routes() - route = routes[0] - self.assertEqual(len(routes), 1) - self.assertEqual(route.name, 'foo') - self.assertEqual(route.path, '/foo') - - def test_deferred_discriminator(self): - # see https://github.com/Pylons/pyramid/issues/2697 - from pyramid.config import PHASE0_CONFIG - - config = self._makeConfigurator() - - def deriver(view, info): - return view - - deriver.options = ('foo',) - config.add_view_deriver(deriver, 'foo_view') - # add_view uses a deferred discriminator and will fail if executed - # prior to add_view_deriver executing its action - config.add_view(lambda r: r.response, name='', foo=1) - - def dummy_action(): - # trigger a re-entrant action - config.action(None, lambda: None) - - config.action(None, dummy_action, order=PHASE0_CONFIG) - config.commit() - - -class Test_resolveConflicts(unittest.TestCase): - def _callFUT(self, actions): - from pyramid.config import resolveConflicts - - return resolveConflicts(actions) - - def test_it_success_tuples(self): - from . import dummyfactory as f - - result = self._callFUT( - [ - (None, f), - (1, f, (1,), {}, (), 'first'), - (1, f, (2,), {}, ('x',), 'second'), - (1, f, (3,), {}, ('y',), 'third'), - (4, f, (4,), {}, ('y',), 'should be last', 99999), - (3, f, (3,), {}, ('y',)), - (None, f, (5,), {}, ('y',)), - ] - ) - result = list(result) - self.assertEqual( - result, - [ - { - 'info': None, - 'args': (), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': (), - 'order': 0, - }, - { - 'info': 'first', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 1, - 'includepath': (), - 'order': 0, - }, - { - 'info': None, - 'args': (3,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 3, - 'includepath': ('y',), - 'order': 0, - }, - { - 'info': None, - 'args': (5,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': ('y',), - 'order': 0, - }, - { - 'info': 'should be last', - 'args': (4,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 4, - 'includepath': ('y',), - 'order': 99999, - }, - ], - ) - - def test_it_success_dicts(self): - from . import dummyfactory as f - - result = self._callFUT( - [ - (None, f), - (1, f, (1,), {}, (), 'first'), - (1, f, (2,), {}, ('x',), 'second'), - (1, f, (3,), {}, ('y',), 'third'), - (4, f, (4,), {}, ('y',), 'should be last', 99999), - (3, f, (3,), {}, ('y',)), - (None, f, (5,), {}, ('y',)), - ] - ) - result = list(result) - self.assertEqual( - result, - [ - { - 'info': None, - 'args': (), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': (), - 'order': 0, - }, - { - 'info': 'first', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 1, - 'includepath': (), - 'order': 0, - }, - { - 'info': None, - 'args': (3,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 3, - 'includepath': ('y',), - 'order': 0, - }, - { - 'info': None, - 'args': (5,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': ('y',), - 'order': 0, - }, - { - 'info': 'should be last', - 'args': (4,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 4, - 'includepath': ('y',), - 'order': 99999, - }, - ], - ) - - def test_it_conflict(self): - from . import dummyfactory as f - - result = self._callFUT( - [ - (None, f), - (1, f, (2,), {}, ('x',), 'eek'), # will conflict - (1, f, (3,), {}, ('y',), 'ack'), # will conflict - (4, f, (4,), {}, ('y',)), - (3, f, (3,), {}, ('y',)), - (None, f, (5,), {}, ('y',)), - ] - ) - self.assertRaises(ConfigurationConflictError, list, result) - - def test_it_with_actions_grouped_by_order(self): - from . import dummyfactory as f - - result = self._callFUT( - [ - (None, f), # X - (1, f, (1,), {}, (), 'third', 10), # X - (1, f, (2,), {}, ('x',), 'fourth', 10), - (1, f, (3,), {}, ('y',), 'fifth', 10), - (2, f, (1,), {}, (), 'sixth', 10), # X - (3, f, (1,), {}, (), 'seventh', 10), # X - (5, f, (4,), {}, ('y',), 'eighth', 99999), # X - (4, f, (3,), {}, (), 'first', 5), # X - (4, f, (5,), {}, ('y',), 'second', 5), - ] - ) - result = list(result) - self.assertEqual(len(result), 6) - # resolved actions should be grouped by (order, i) - self.assertEqual( - result, - [ - { - 'info': None, - 'args': (), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': (), - 'order': 0, - }, - { - 'info': 'first', - 'args': (3,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 4, - 'includepath': (), - 'order': 5, - }, - { - 'info': 'third', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 1, - 'includepath': (), - 'order': 10, - }, - { - 'info': 'sixth', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 2, - 'includepath': (), - 'order': 10, - }, - { - 'info': 'seventh', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 3, - 'includepath': (), - 'order': 10, - }, - { - 'info': 'eighth', - 'args': (4,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 5, - 'includepath': ('y',), - 'order': 99999, - }, - ], - ) - - def test_override_success_across_orders(self): - from . import dummyfactory as f - - result = self._callFUT( - [ - (1, f, (2,), {}, ('x',), 'eek', 0), - (1, f, (3,), {}, ('x', 'y'), 'ack', 10), - ] - ) - result = list(result) - self.assertEqual( - result, - [ - { - 'info': 'eek', - 'args': (2,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 1, - 'includepath': ('x',), - 'order': 0, - } - ], - ) - - def test_conflicts_across_orders(self): - from . import dummyfactory as f - - result = self._callFUT( - [ - (1, f, (2,), {}, ('x', 'y'), 'eek', 0), - (1, f, (3,), {}, ('x'), 'ack', 10), - ] - ) - self.assertRaises(ConfigurationConflictError, list, result) - - class TestGlobalRegistriesIntegration(unittest.TestCase): def setUp(self): from pyramid.config import global_registries @@ -2430,11 +1432,6 @@ class DummyThreadLocalManager(object): self.popped = True -@implementer(IDummy) -class DummyEvent: - pass - - class DummyRegistry(object): def __init__(self, adaptation=None, util=None): self.utilities = [] @@ -2459,35 +1456,5 @@ class DummyRegistry(object): return self.util -class IOther(Interface): - pass - - -def _conflictFunctions(e): - conflicts = e._conflicts.values() - for conflict in conflicts: - for confinst in conflict: - yield confinst.function - - -class DummyActionState(object): - autocommit = False - info = '' - - def __init__(self): - self.actions = [] - - def action(self, *arg, **kw): - self.actions.append((arg, kw)) - - -class DummyIntrospectable(object): - def __init__(self): - self.registered = [] - - def register(self, introspector, action_info): - self.registered.append((introspector, action_info)) - - class DummyPredicate(object): pass diff --git a/tests/test_config/test_testing.py b/tests/test_config/test_testing.py index ce6659667..ede31e1b6 100644 --- a/tests/test_config/test_testing.py +++ b/tests/test_config/test_testing.py @@ -104,7 +104,7 @@ class TestingConfiguratorMixinTests(unittest.TestCase): def test_testing_add_subscriber_dottedname(self): config = self._makeOne(autocommit=True) - L = config.testing_add_subscriber('tests.test_config.test_init.IDummy') + L = config.testing_add_subscriber('tests.test_config.IDummy') event = DummyEvent() config.registry.notify(event) self.assertEqual(len(L), 1) -- cgit v1.2.3 From d579f2104de139e0b0fc5d6c81aabb2f826e5e54 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 18 Oct 2018 20:44:42 -0500 Subject: move predicate-related code into pyramid.config.predicates --- tests/test_config/test_actions.py | 37 ++- tests/test_config/test_predicates.py | 480 ++++++++++++++++++++++++++++++++ tests/test_config/test_util.py | 526 ----------------------------------- tests/test_config/test_views.py | 4 +- tests/test_viewderivers.py | 2 +- 5 files changed, 519 insertions(+), 530 deletions(-) create mode 100644 tests/test_config/test_predicates.py delete mode 100644 tests/test_config/test_util.py (limited to 'tests') diff --git a/tests/test_config/test_actions.py b/tests/test_config/test_actions.py index ba8b8c124..098f73585 100644 --- a/tests/test_config/test_actions.py +++ b/tests/test_config/test_actions.py @@ -50,7 +50,7 @@ class ConfiguratorTests(unittest.TestCase): self.assertEqual(config.action('discrim', kw={'a': 1}), None) def test_action_autocommit_with_introspectables(self): - from pyramid.config.util import ActionInfo + from pyramid.config.actions import ActionInfo config = self._makeOne(autocommit=True) intr = DummyIntrospectable() @@ -1029,6 +1029,41 @@ class Test_resolveConflicts(unittest.TestCase): self.assertRaises(ConfigurationConflictError, list, result) +class TestActionInfo(unittest.TestCase): + def _getTargetClass(self): + from pyramid.config.actions import ActionInfo + + return ActionInfo + + def _makeOne(self, filename, lineno, function, linerepr): + return self._getTargetClass()(filename, lineno, function, linerepr) + + def test_class_conforms(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IActionInfo + + verifyClass(IActionInfo, self._getTargetClass()) + + def test_instance_conforms(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IActionInfo + + verifyObject(IActionInfo, self._makeOne('f', 0, 'f', 'f')) + + def test_ctor(self): + inst = self._makeOne('filename', 10, 'function', 'src') + self.assertEqual(inst.file, 'filename') + self.assertEqual(inst.line, 10) + self.assertEqual(inst.function, 'function') + self.assertEqual(inst.src, 'src') + + def test___str__(self): + inst = self._makeOne('filename', 0, 'function', ' linerepr ') + self.assertEqual( + str(inst), "Line 0 of file filename:\n linerepr " + ) + + def _conflictFunctions(e): conflicts = e._conflicts.values() for conflict in conflicts: diff --git a/tests/test_config/test_predicates.py b/tests/test_config/test_predicates.py new file mode 100644 index 000000000..079652b39 --- /dev/null +++ b/tests/test_config/test_predicates.py @@ -0,0 +1,480 @@ +import unittest + +from pyramid.compat import text_ + + +class TestPredicateList(unittest.TestCase): + def _makeOne(self): + from pyramid.config.predicates import PredicateList + from pyramid import predicates + + inst = PredicateList() + for name, factory in ( + ('xhr', predicates.XHRPredicate), + ('request_method', predicates.RequestMethodPredicate), + ('path_info', predicates.PathInfoPredicate), + ('request_param', predicates.RequestParamPredicate), + ('header', predicates.HeaderPredicate), + ('accept', predicates.AcceptPredicate), + ('containment', predicates.ContainmentPredicate), + ('request_type', predicates.RequestTypePredicate), + ('match_param', predicates.MatchParamPredicate), + ('custom', predicates.CustomPredicate), + ('traverse', predicates.TraversePredicate), + ): + inst.add(name, factory) + return inst + + def _callFUT(self, **kw): + inst = self._makeOne() + config = DummyConfigurator() + return inst.make(config, **kw) + + def test_ordering_xhr_and_request_method_trump_only_containment(self): + order1, _, _ = self._callFUT(xhr=True, request_method='GET') + order2, _, _ = self._callFUT(containment=True) + self.assertTrue(order1 < order2) + + def test_ordering_number_of_predicates(self): + from pyramid.config.predicates import predvalseq + + order1, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + containment='containment', + request_type='request_type', + custom=predvalseq([DummyCustomPredicate()]), + ) + order2, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + containment='containment', + request_type='request_type', + custom=predvalseq([DummyCustomPredicate()]), + ) + order3, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + containment='containment', + request_type='request_type', + ) + order4, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + containment='containment', + ) + order5, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + ) + order6, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + ) + order7, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + ) + order8, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + ) + order9, _, _ = self._callFUT( + xhr='xhr', request_method='request_method', path_info='path_info' + ) + order10, _, _ = self._callFUT( + xhr='xhr', request_method='request_method' + ) + order11, _, _ = self._callFUT(xhr='xhr') + order12, _, _ = self._callFUT() + self.assertEqual(order1, order2) + self.assertTrue(order3 > order2) + self.assertTrue(order4 > order3) + self.assertTrue(order5 > order4) + self.assertTrue(order6 > order5) + self.assertTrue(order7 > order6) + self.assertTrue(order8 > order7) + self.assertTrue(order9 > order8) + self.assertTrue(order10 > order9) + self.assertTrue(order11 > order10) + self.assertTrue(order12 > order10) + + def test_ordering_importance_of_predicates(self): + from pyramid.config.predicates import predvalseq + + order1, _, _ = self._callFUT(xhr='xhr') + order2, _, _ = self._callFUT(request_method='request_method') + order3, _, _ = self._callFUT(path_info='path_info') + order4, _, _ = self._callFUT(request_param='param') + order5, _, _ = self._callFUT(header='header') + order6, _, _ = self._callFUT(accept='accept') + order7, _, _ = self._callFUT(containment='containment') + order8, _, _ = self._callFUT(request_type='request_type') + order9, _, _ = self._callFUT(match_param='foo=bar') + order10, _, _ = self._callFUT( + custom=predvalseq([DummyCustomPredicate()]) + ) + self.assertTrue(order1 > order2) + self.assertTrue(order2 > order3) + self.assertTrue(order3 > order4) + self.assertTrue(order4 > order5) + self.assertTrue(order5 > order6) + self.assertTrue(order6 > order7) + self.assertTrue(order7 > order8) + self.assertTrue(order8 > order9) + self.assertTrue(order9 > order10) + + def test_ordering_importance_and_number(self): + from pyramid.config.predicates import predvalseq + + order1, _, _ = self._callFUT( + xhr='xhr', request_method='request_method' + ) + order2, _, _ = self._callFUT( + custom=predvalseq([DummyCustomPredicate()]) + ) + self.assertTrue(order1 < order2) + + order1, _, _ = self._callFUT( + xhr='xhr', request_method='request_method' + ) + order2, _, _ = self._callFUT( + request_method='request_method', + custom=predvalseq([DummyCustomPredicate()]), + ) + self.assertTrue(order1 > order2) + + order1, _, _ = self._callFUT( + xhr='xhr', request_method='request_method', path_info='path_info' + ) + order2, _, _ = self._callFUT( + request_method='request_method', + custom=predvalseq([DummyCustomPredicate()]), + ) + self.assertTrue(order1 < order2) + + order1, _, _ = self._callFUT( + xhr='xhr', request_method='request_method', path_info='path_info' + ) + order2, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + custom=predvalseq([DummyCustomPredicate()]), + ) + self.assertTrue(order1 > order2) + + def test_different_custom_predicates_with_same_hash(self): + from pyramid.config.predicates import predvalseq + + class PredicateWithHash(object): + def __hash__(self): + return 1 + + a = PredicateWithHash() + b = PredicateWithHash() + _, _, a_phash = self._callFUT(custom=predvalseq([a])) + _, _, b_phash = self._callFUT(custom=predvalseq([b])) + self.assertEqual(a_phash, b_phash) + + def test_traverse_has_remainder_already(self): + order, predicates, phash = self._callFUT(traverse='/1/:a/:b') + self.assertEqual(len(predicates), 1) + pred = predicates[0] + info = {'traverse': 'abc'} + request = DummyRequest() + result = pred(info, request) + self.assertEqual(result, True) + self.assertEqual(info, {'traverse': 'abc'}) + + def test_traverse_matches(self): + order, predicates, phash = self._callFUT(traverse='/1/:a/:b') + self.assertEqual(len(predicates), 1) + pred = predicates[0] + info = {'match': {'a': 'a', 'b': 'b'}} + request = DummyRequest() + result = pred(info, request) + self.assertEqual(result, True) + self.assertEqual( + info, {'match': {'a': 'a', 'b': 'b', 'traverse': ('1', 'a', 'b')}} + ) + + def test_traverse_matches_with_highorder_chars(self): + order, predicates, phash = self._callFUT( + traverse=text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8') + ) + self.assertEqual(len(predicates), 1) + pred = predicates[0] + info = {'match': {'x': text_(b'Qu\xc3\xa9bec', 'utf-8')}} + request = DummyRequest() + result = pred(info, request) + self.assertEqual(result, True) + self.assertEqual( + info['match']['traverse'], + ( + text_(b'La Pe\xc3\xb1a', 'utf-8'), + text_(b'Qu\xc3\xa9bec', 'utf-8'), + ), + ) + + def test_custom_predicates_can_affect_traversal(self): + from pyramid.config.predicates import predvalseq + + def custom(info, request): + m = info['match'] + m['dummy'] = 'foo' + return True + + _, predicates, _ = self._callFUT( + custom=predvalseq([custom]), traverse='/1/:dummy/:a' + ) + self.assertEqual(len(predicates), 2) + info = {'match': {'a': 'a'}} + request = DummyRequest() + self.assertTrue(all([p(info, request) for p in predicates])) + self.assertEqual( + info, + { + 'match': { + 'a': 'a', + 'dummy': 'foo', + 'traverse': ('1', 'foo', 'a'), + } + }, + ) + + def test_predicate_text_is_correct(self): + from pyramid.config.predicates import predvalseq + + _, 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=predvalseq( + [ + DummyCustomPredicate(), + DummyCustomPredicate.classmethod_predicate, + DummyCustomPredicate.classmethod_predicate_no_text, + ] + ), + match_param='foo=bar', + ) + 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(), "match_param foo=bar") + self.assertEqual(predicates[9].text(), 'custom predicate') + self.assertEqual(predicates[10].text(), 'classmethod predicate') + self.assertTrue(predicates[11].text().startswith('custom predicate')) + + def test_match_param_from_string(self): + _, predicates, _ = self._callFUT(match_param='foo=bar') + request = DummyRequest() + request.matchdict = {'foo': 'bar', 'baz': 'bum'} + self.assertTrue(predicates[0](Dummy(), request)) + + def test_match_param_from_string_fails(self): + _, predicates, _ = self._callFUT(match_param='foo=bar') + request = DummyRequest() + request.matchdict = {'foo': 'bum', 'baz': 'bum'} + self.assertFalse(predicates[0](Dummy(), request)) + + def test_match_param_from_dict(self): + _, predicates, _ = self._callFUT(match_param=('foo=bar', 'baz=bum')) + request = DummyRequest() + request.matchdict = {'foo': 'bar', 'baz': 'bum'} + self.assertTrue(predicates[0](Dummy(), request)) + + def test_match_param_from_dict_fails(self): + _, predicates, _ = self._callFUT(match_param=('foo=bar', 'baz=bum')) + request = DummyRequest() + request.matchdict = {'foo': 'bar', 'baz': 'foo'} + self.assertFalse(predicates[0](Dummy(), request)) + + def test_request_method_sequence(self): + _, predicates, _ = self._callFUT(request_method=('GET', 'HEAD')) + request = DummyRequest() + request.method = 'HEAD' + self.assertTrue(predicates[0](Dummy(), request)) + request.method = 'GET' + self.assertTrue(predicates[0](Dummy(), request)) + request.method = 'POST' + self.assertFalse(predicates[0](Dummy(), request)) + + def test_request_method_ordering_hashes_same(self): + hash1, _, __ = self._callFUT(request_method=('GET', 'HEAD')) + hash2, _, __ = self._callFUT(request_method=('HEAD', 'GET')) + self.assertEqual(hash1, hash2) + hash1, _, __ = self._callFUT(request_method=('GET',)) + hash2, _, __ = self._callFUT(request_method='GET') + self.assertEqual(hash1, hash2) + + def test_unknown_predicate(self): + from pyramid.exceptions import ConfigurationError + + self.assertRaises(ConfigurationError, self._callFUT, unknown=1) + + def test_predicate_close_matches(self): + from pyramid.exceptions import ConfigurationError + + with self.assertRaises(ConfigurationError) as context: + self._callFUT(method='GET') + expected_msg = ( + "Unknown predicate values: {'method': 'GET'} " + "(did you mean request_method)" + ) + self.assertEqual(context.exception.args[0], expected_msg) + + def test_notted(self): + from pyramid.config import not_ + from pyramid.testing import DummyRequest + + request = DummyRequest() + _, predicates, _ = self._callFUT( + xhr='xhr', request_method=not_('POST'), header=not_('header') + ) + self.assertEqual(predicates[0].text(), 'xhr = True') + self.assertEqual(predicates[1].text(), "!request_method = POST") + self.assertEqual(predicates[2].text(), '!header header') + self.assertEqual(predicates[1](None, request), True) + self.assertEqual(predicates[2](None, request), True) + + +class Test_sort_accept_offers(unittest.TestCase): + def _callFUT(self, offers, order=None): + from pyramid.config.predicates import sort_accept_offers + + return sort_accept_offers(offers, order) + + def test_default_specificities(self): + result = self._callFUT(['text/html', 'text/html;charset=utf8']) + self.assertEqual(result, ['text/html;charset=utf8', 'text/html']) + + def test_specific_type_order(self): + result = self._callFUT( + [ + 'text/html', + 'application/json', + 'text/html;charset=utf8', + 'text/plain', + ], + ['application/json', 'text/html'], + ) + self.assertEqual( + result, + [ + 'application/json', + 'text/html;charset=utf8', + 'text/html', + 'text/plain', + ], + ) + + def test_params_order(self): + result = self._callFUT( + [ + 'text/html;charset=utf8', + 'text/html;charset=latin1', + 'text/html;foo=bar', + ], + ['text/html;charset=latin1', 'text/html;charset=utf8'], + ) + self.assertEqual( + result, + [ + 'text/html;charset=latin1', + 'text/html;charset=utf8', + 'text/html;foo=bar', + ], + ) + + def test_params_inherit_type_prefs(self): + result = self._callFUT( + ['text/html;charset=utf8', 'text/plain;charset=latin1'], + ['text/plain', 'text/html'], + ) + self.assertEqual( + result, ['text/plain;charset=latin1', 'text/html;charset=utf8'] + ) + + +class DummyCustomPredicate(object): + def __init__(self): + self.__text__ = 'custom predicate' + + def classmethod_predicate(*args): # pragma: no cover + pass + + classmethod_predicate.__text__ = 'classmethod predicate' + classmethod_predicate = classmethod(classmethod_predicate) + + @classmethod + def classmethod_predicate_no_text(*args): + pass # pragma: no cover + + +class Dummy(object): + def __init__(self, **kw): + self.__dict__.update(**kw) + + +class DummyRequest: + subpath = () + matchdict = None + + def __init__(self, environ=None): + if environ is None: + environ = {} + self.environ = environ + self.params = {} + self.cookies = {} + + +class DummyConfigurator(object): + def maybe_dotted(self, thing): + return thing diff --git a/tests/test_config/test_util.py b/tests/test_config/test_util.py deleted file mode 100644 index 50d143b2d..000000000 --- a/tests/test_config/test_util.py +++ /dev/null @@ -1,526 +0,0 @@ -import unittest - -from pyramid.compat import text_ - - -class TestActionInfo(unittest.TestCase): - def _getTargetClass(self): - from pyramid.config.util import ActionInfo - - return ActionInfo - - def _makeOne(self, filename, lineno, function, linerepr): - return self._getTargetClass()(filename, lineno, function, linerepr) - - def test_class_conforms(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IActionInfo - - verifyClass(IActionInfo, self._getTargetClass()) - - def test_instance_conforms(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IActionInfo - - verifyObject(IActionInfo, self._makeOne('f', 0, 'f', 'f')) - - def test_ctor(self): - inst = self._makeOne('filename', 10, 'function', 'src') - self.assertEqual(inst.file, 'filename') - self.assertEqual(inst.line, 10) - self.assertEqual(inst.function, 'function') - self.assertEqual(inst.src, 'src') - - def test___str__(self): - inst = self._makeOne('filename', 0, 'function', ' linerepr ') - self.assertEqual( - str(inst), "Line 0 of file filename:\n linerepr " - ) - - -class TestPredicateList(unittest.TestCase): - def _makeOne(self): - from pyramid.config.util import PredicateList - from pyramid import predicates - - inst = PredicateList() - for name, factory in ( - ('xhr', predicates.XHRPredicate), - ('request_method', predicates.RequestMethodPredicate), - ('path_info', predicates.PathInfoPredicate), - ('request_param', predicates.RequestParamPredicate), - ('header', predicates.HeaderPredicate), - ('accept', predicates.AcceptPredicate), - ('containment', predicates.ContainmentPredicate), - ('request_type', predicates.RequestTypePredicate), - ('match_param', predicates.MatchParamPredicate), - ('custom', predicates.CustomPredicate), - ('traverse', predicates.TraversePredicate), - ): - inst.add(name, factory) - return inst - - def _callFUT(self, **kw): - inst = self._makeOne() - config = DummyConfigurator() - return inst.make(config, **kw) - - def test_ordering_xhr_and_request_method_trump_only_containment(self): - order1, _, _ = self._callFUT(xhr=True, request_method='GET') - order2, _, _ = self._callFUT(containment=True) - self.assertTrue(order1 < order2) - - def test_ordering_number_of_predicates(self): - from pyramid.config.util import predvalseq - - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - custom=predvalseq([DummyCustomPredicate()]), - ) - order2, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - custom=predvalseq([DummyCustomPredicate()]), - ) - order3, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - ) - order4, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - containment='containment', - ) - order5, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - ) - order6, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - ) - order7, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - ) - order8, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - ) - order9, _, _ = self._callFUT( - xhr='xhr', request_method='request_method', path_info='path_info' - ) - order10, _, _ = self._callFUT( - xhr='xhr', request_method='request_method' - ) - order11, _, _ = self._callFUT(xhr='xhr') - order12, _, _ = self._callFUT() - self.assertEqual(order1, order2) - self.assertTrue(order3 > order2) - self.assertTrue(order4 > order3) - self.assertTrue(order5 > order4) - self.assertTrue(order6 > order5) - self.assertTrue(order7 > order6) - self.assertTrue(order8 > order7) - self.assertTrue(order9 > order8) - self.assertTrue(order10 > order9) - self.assertTrue(order11 > order10) - self.assertTrue(order12 > order10) - - def test_ordering_importance_of_predicates(self): - from pyramid.config.util import predvalseq - - order1, _, _ = self._callFUT(xhr='xhr') - order2, _, _ = self._callFUT(request_method='request_method') - order3, _, _ = self._callFUT(path_info='path_info') - order4, _, _ = self._callFUT(request_param='param') - order5, _, _ = self._callFUT(header='header') - order6, _, _ = self._callFUT(accept='accept') - order7, _, _ = self._callFUT(containment='containment') - order8, _, _ = self._callFUT(request_type='request_type') - order9, _, _ = self._callFUT(match_param='foo=bar') - order10, _, _ = self._callFUT( - custom=predvalseq([DummyCustomPredicate()]) - ) - self.assertTrue(order1 > order2) - self.assertTrue(order2 > order3) - self.assertTrue(order3 > order4) - self.assertTrue(order4 > order5) - self.assertTrue(order5 > order6) - self.assertTrue(order6 > order7) - self.assertTrue(order7 > order8) - self.assertTrue(order8 > order9) - self.assertTrue(order9 > order10) - - def test_ordering_importance_and_number(self): - from pyramid.config.util import predvalseq - - order1, _, _ = self._callFUT( - xhr='xhr', request_method='request_method' - ) - order2, _, _ = self._callFUT( - custom=predvalseq([DummyCustomPredicate()]) - ) - self.assertTrue(order1 < order2) - - order1, _, _ = self._callFUT( - xhr='xhr', request_method='request_method' - ) - order2, _, _ = self._callFUT( - request_method='request_method', - custom=predvalseq([DummyCustomPredicate()]), - ) - self.assertTrue(order1 > order2) - - order1, _, _ = self._callFUT( - xhr='xhr', request_method='request_method', path_info='path_info' - ) - order2, _, _ = self._callFUT( - request_method='request_method', - custom=predvalseq([DummyCustomPredicate()]), - ) - self.assertTrue(order1 < order2) - - order1, _, _ = self._callFUT( - xhr='xhr', request_method='request_method', path_info='path_info' - ) - order2, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - custom=predvalseq([DummyCustomPredicate()]), - ) - self.assertTrue(order1 > order2) - - def test_different_custom_predicates_with_same_hash(self): - from pyramid.config.util import predvalseq - - class PredicateWithHash(object): - def __hash__(self): - return 1 - - a = PredicateWithHash() - b = PredicateWithHash() - _, _, a_phash = self._callFUT(custom=predvalseq([a])) - _, _, b_phash = self._callFUT(custom=predvalseq([b])) - self.assertEqual(a_phash, b_phash) - - def test_traverse_has_remainder_already(self): - order, predicates, phash = self._callFUT(traverse='/1/:a/:b') - self.assertEqual(len(predicates), 1) - pred = predicates[0] - info = {'traverse': 'abc'} - request = DummyRequest() - result = pred(info, request) - self.assertEqual(result, True) - self.assertEqual(info, {'traverse': 'abc'}) - - def test_traverse_matches(self): - order, predicates, phash = self._callFUT(traverse='/1/:a/:b') - self.assertEqual(len(predicates), 1) - pred = predicates[0] - info = {'match': {'a': 'a', 'b': 'b'}} - request = DummyRequest() - result = pred(info, request) - self.assertEqual(result, True) - self.assertEqual( - info, {'match': {'a': 'a', 'b': 'b', 'traverse': ('1', 'a', 'b')}} - ) - - def test_traverse_matches_with_highorder_chars(self): - order, predicates, phash = self._callFUT( - traverse=text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8') - ) - self.assertEqual(len(predicates), 1) - pred = predicates[0] - info = {'match': {'x': text_(b'Qu\xc3\xa9bec', 'utf-8')}} - request = DummyRequest() - result = pred(info, request) - self.assertEqual(result, True) - self.assertEqual( - info['match']['traverse'], - ( - text_(b'La Pe\xc3\xb1a', 'utf-8'), - text_(b'Qu\xc3\xa9bec', 'utf-8'), - ), - ) - - def test_custom_predicates_can_affect_traversal(self): - from pyramid.config.util import predvalseq - - def custom(info, request): - m = info['match'] - m['dummy'] = 'foo' - return True - - _, predicates, _ = self._callFUT( - custom=predvalseq([custom]), traverse='/1/:dummy/:a' - ) - self.assertEqual(len(predicates), 2) - info = {'match': {'a': 'a'}} - request = DummyRequest() - self.assertTrue(all([p(info, request) for p in predicates])) - self.assertEqual( - info, - { - 'match': { - 'a': 'a', - 'dummy': 'foo', - 'traverse': ('1', 'foo', 'a'), - } - }, - ) - - def test_predicate_text_is_correct(self): - from pyramid.config.util import predvalseq - - _, 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=predvalseq( - [ - DummyCustomPredicate(), - DummyCustomPredicate.classmethod_predicate, - DummyCustomPredicate.classmethod_predicate_no_text, - ] - ), - match_param='foo=bar', - ) - 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(), "match_param foo=bar") - self.assertEqual(predicates[9].text(), 'custom predicate') - self.assertEqual(predicates[10].text(), 'classmethod predicate') - self.assertTrue(predicates[11].text().startswith('custom predicate')) - - def test_match_param_from_string(self): - _, predicates, _ = self._callFUT(match_param='foo=bar') - request = DummyRequest() - request.matchdict = {'foo': 'bar', 'baz': 'bum'} - self.assertTrue(predicates[0](Dummy(), request)) - - def test_match_param_from_string_fails(self): - _, predicates, _ = self._callFUT(match_param='foo=bar') - request = DummyRequest() - request.matchdict = {'foo': 'bum', 'baz': 'bum'} - self.assertFalse(predicates[0](Dummy(), request)) - - def test_match_param_from_dict(self): - _, predicates, _ = self._callFUT(match_param=('foo=bar', 'baz=bum')) - request = DummyRequest() - request.matchdict = {'foo': 'bar', 'baz': 'bum'} - self.assertTrue(predicates[0](Dummy(), request)) - - def test_match_param_from_dict_fails(self): - _, predicates, _ = self._callFUT(match_param=('foo=bar', 'baz=bum')) - request = DummyRequest() - request.matchdict = {'foo': 'bar', 'baz': 'foo'} - self.assertFalse(predicates[0](Dummy(), request)) - - def test_request_method_sequence(self): - _, predicates, _ = self._callFUT(request_method=('GET', 'HEAD')) - request = DummyRequest() - request.method = 'HEAD' - self.assertTrue(predicates[0](Dummy(), request)) - request.method = 'GET' - self.assertTrue(predicates[0](Dummy(), request)) - request.method = 'POST' - self.assertFalse(predicates[0](Dummy(), request)) - - def test_request_method_ordering_hashes_same(self): - hash1, _, __ = self._callFUT(request_method=('GET', 'HEAD')) - hash2, _, __ = self._callFUT(request_method=('HEAD', 'GET')) - self.assertEqual(hash1, hash2) - hash1, _, __ = self._callFUT(request_method=('GET',)) - hash2, _, __ = self._callFUT(request_method='GET') - self.assertEqual(hash1, hash2) - - def test_unknown_predicate(self): - from pyramid.exceptions import ConfigurationError - - self.assertRaises(ConfigurationError, self._callFUT, unknown=1) - - def test_predicate_close_matches(self): - from pyramid.exceptions import ConfigurationError - - with self.assertRaises(ConfigurationError) as context: - self._callFUT(method='GET') - expected_msg = ( - "Unknown predicate values: {'method': 'GET'} " - "(did you mean request_method)" - ) - self.assertEqual(context.exception.args[0], expected_msg) - - def test_notted(self): - from pyramid.config import not_ - from pyramid.testing import DummyRequest - - request = DummyRequest() - _, predicates, _ = self._callFUT( - xhr='xhr', request_method=not_('POST'), header=not_('header') - ) - self.assertEqual(predicates[0].text(), 'xhr = True') - self.assertEqual(predicates[1].text(), "!request_method = POST") - self.assertEqual(predicates[2].text(), '!header header') - self.assertEqual(predicates[1](None, request), True) - self.assertEqual(predicates[2](None, request), True) - - -class TestDeprecatedPredicates(unittest.TestCase): - def test_it(self): - import warnings - - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - from pyramid.config.predicates import XHRPredicate # noqa: F401 - - self.assertEqual(len(w), 1) - - -class Test_sort_accept_offers(unittest.TestCase): - def _callFUT(self, offers, order=None): - from pyramid.config.util import sort_accept_offers - - return sort_accept_offers(offers, order) - - def test_default_specificities(self): - result = self._callFUT(['text/html', 'text/html;charset=utf8']) - self.assertEqual(result, ['text/html;charset=utf8', 'text/html']) - - def test_specific_type_order(self): - result = self._callFUT( - [ - 'text/html', - 'application/json', - 'text/html;charset=utf8', - 'text/plain', - ], - ['application/json', 'text/html'], - ) - self.assertEqual( - result, - [ - 'application/json', - 'text/html;charset=utf8', - 'text/html', - 'text/plain', - ], - ) - - def test_params_order(self): - result = self._callFUT( - [ - 'text/html;charset=utf8', - 'text/html;charset=latin1', - 'text/html;foo=bar', - ], - ['text/html;charset=latin1', 'text/html;charset=utf8'], - ) - self.assertEqual( - result, - [ - 'text/html;charset=latin1', - 'text/html;charset=utf8', - 'text/html;foo=bar', - ], - ) - - def test_params_inherit_type_prefs(self): - result = self._callFUT( - ['text/html;charset=utf8', 'text/plain;charset=latin1'], - ['text/plain', 'text/html'], - ) - self.assertEqual( - result, ['text/plain;charset=latin1', 'text/html;charset=utf8'] - ) - - -class DummyCustomPredicate(object): - def __init__(self): - self.__text__ = 'custom predicate' - - def classmethod_predicate(*args): # pragma: no cover - pass - - classmethod_predicate.__text__ = 'classmethod predicate' - classmethod_predicate = classmethod(classmethod_predicate) - - @classmethod - def classmethod_predicate_no_text(*args): - pass # pragma: no cover - - -class Dummy(object): - def __init__(self, **kw): - self.__dict__.update(**kw) - - -class DummyRequest: - subpath = () - matchdict = None - - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - self.params = {} - self.cookies = {} - - -class DummyConfigurator(object): - def maybe_dotted(self, thing): - return thing diff --git a/tests/test_config/test_views.py b/tests/test_config/test_views.py index 977944fdd..5e722c9a0 100644 --- a/tests/test_config/test_views.py +++ b/tests/test_config/test_views.py @@ -664,7 +664,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): self.assertEqual(wrapper(None, request), 'OK') def test_add_view_default_phash_overrides_default_phash(self): - from pyramid.config.util import DEFAULT_PHASH + from pyramid.config.predicates import DEFAULT_PHASH from pyramid.renderers import null_renderer from zope.interface import Interface from pyramid.interfaces import IRequest @@ -690,7 +690,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): self.assertEqual(wrapper(None, request), 'OK') def test_add_view_exc_default_phash_overrides_default_phash(self): - from pyramid.config.util import DEFAULT_PHASH + from pyramid.config.predicates import DEFAULT_PHASH from pyramid.renderers import null_renderer from zope.interface import implementedBy from pyramid.interfaces import IRequest diff --git a/tests/test_viewderivers.py b/tests/test_viewderivers.py index a1455ed92..f01cb490e 100644 --- a/tests/test_viewderivers.py +++ b/tests/test_viewderivers.py @@ -1265,7 +1265,7 @@ class TestDeriveView(unittest.TestCase): self.assertEqual(result(None, None), response) def test_attr_wrapped_view_branching_default_phash(self): - from pyramid.config.util import DEFAULT_PHASH + from pyramid.config.predicates import DEFAULT_PHASH def view(context, request): # pragma: no cover pass -- cgit v1.2.3 From 69ea9e4ad7e11581d724ffe91aa66935a62c06d7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 18 Oct 2018 21:25:36 -0500 Subject: fix coverage --- tests/test_config/test_actions.py | 2 +- tests/test_config/test_init.py | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/test_config/test_actions.py b/tests/test_config/test_actions.py index 098f73585..a72d0d7b1 100644 --- a/tests/test_config/test_actions.py +++ b/tests/test_config/test_actions.py @@ -6,7 +6,7 @@ from pyramid.exceptions import ConfigurationExecutionError from pyramid.interfaces import IRequest -class ConfiguratorTests(unittest.TestCase): +class ActionConfiguratorMixinTests(unittest.TestCase): def _makeOne(self, *arg, **kw): from pyramid.config import Configurator diff --git a/tests/test_config/test_init.py b/tests/test_config/test_init.py index 8216b5557..811672fb3 100644 --- a/tests/test_config/test_init.py +++ b/tests/test_config/test_init.py @@ -31,7 +31,6 @@ class ConfiguratorTests(unittest.TestCase): name='', exception_view=False, ): - from zope.interface import Interface from pyramid.interfaces import IView from pyramid.interfaces import IViewClassifier from pyramid.interfaces import IExceptionViewClassifier @@ -40,10 +39,6 @@ class ConfiguratorTests(unittest.TestCase): classifier = IExceptionViewClassifier else: classifier = IViewClassifier - if ctx_iface is None: - ctx_iface = Interface - if request_iface is None: - request_iface = IRequest return config.registry.adapters.lookup( (classifier, request_iface, ctx_iface), IView, -- cgit v1.2.3