Michael Merickel
2018-10-15 10ddb6f08592c2740b966e98a6f98a5b83af1896
commit | author | age
5bf23f 1 import os
10ddb6 2 import unittest
MM 3 from zope.interface import Interface
4 from zope.interface import implementer
5bf23f 5
fbd01a 6 from pyramid.compat import im_func
CM 7 from pyramid.testing import skip_on
3b7334 8
dd3cc8 9 from . import dummy_tween_factory
MM 10 from . import dummy_include
11 from . import dummy_extend
12 from . import dummy_extend2
13 from . import IDummy
14 from . import DummyContext
5bf23f 15
79ef3d 16 from pyramid.exceptions import ConfigurationExecutionError
CM 17 from pyramid.exceptions import ConfigurationConflictError
849196 18
CM 19 from pyramid.interfaces import IRequest
79ef3d 20
0c29cf 21
427a02 22 class ConfiguratorTests(unittest.TestCase):
CM 23     def _makeOne(self, *arg, **kw):
24         from pyramid.config import Configurator
0c29cf 25
58bc25 26         config = Configurator(*arg, **kw)
CM 27         return config
427a02 28
0c29cf 29     def _getViewCallable(
MM 30         self,
31         config,
32         ctx_iface=None,
33         request_iface=None,
34         name='',
35         exception_view=False,
36     ):
427a02 37         from zope.interface import Interface
CM 38         from pyramid.interfaces import IRequest
39         from pyramid.interfaces import IView
40         from pyramid.interfaces import IViewClassifier
41         from pyramid.interfaces import IExceptionViewClassifier
0c29cf 42
MM 43         if exception_view:  # pragma: no cover
427a02 44             classifier = IExceptionViewClassifier
CM 45         else:
46             classifier = IViewClassifier
47         if ctx_iface is None:
48             ctx_iface = Interface
49         if request_iface is None:
50             request_iface = IRequest
51         return config.registry.adapters.lookup(
0c29cf 52             (classifier, request_iface, ctx_iface),
MM 53             IView,
54             name=name,
55             default=None,
56         )
427a02 57
CM 58     def _registerEventListener(self, config, event_iface=None):
0c29cf 59         if event_iface is None:  # pragma: no cover
427a02 60             from zope.interface import Interface
0c29cf 61
427a02 62             event_iface = Interface
CM 63         L = []
0c29cf 64
427a02 65         def subscriber(*event):
CM 66             L.extend(event)
0c29cf 67
427a02 68         config.registry.registerHandler(subscriber, (event_iface,))
CM 69         return L
70
71     def _makeRequest(self, config):
72         request = DummyRequest()
73         request.registry = config.registry
74         return request
ed7ffe 75
427a02 76     def test_ctor_no_registry(self):
CM 77         import sys
78         from pyramid.interfaces import ISettings
79         from pyramid.config import Configurator
80         from pyramid.interfaces import IRendererFactory
0c29cf 81
427a02 82         config = Configurator()
dd3cc8 83         this_pkg = sys.modules['tests.test_config']
a1d395 84         self.assertTrue(config.registry.getUtility(ISettings))
427a02 85         self.assertEqual(config.package, this_pkg)
381de3 86         config.commit()
a1d395 87         self.assertTrue(config.registry.getUtility(IRendererFactory, 'json'))
CM 88         self.assertTrue(config.registry.getUtility(IRendererFactory, 'string'))
427a02 89
CM 90     def test_begin(self):
91         from pyramid.config import Configurator
0c29cf 92
427a02 93         config = Configurator()
CM 94         manager = DummyThreadLocalManager()
95         config.manager = manager
96         config.begin()
0c29cf 97         self.assertEqual(
MM 98             manager.pushed, {'registry': config.registry, 'request': None}
99         )
427a02 100         self.assertEqual(manager.popped, False)
CM 101
102     def test_begin_with_request(self):
103         from pyramid.config import Configurator
0c29cf 104
427a02 105         config = Configurator()
CM 106         request = object()
107         manager = DummyThreadLocalManager()
108         config.manager = manager
109         config.begin(request=request)
0c29cf 110         self.assertEqual(
MM 111             manager.pushed, {'registry': config.registry, 'request': request}
112         )
427a02 113         self.assertEqual(manager.popped, False)
CM 114
804eb0 115     def test_begin_overrides_request(self):
MM 116         from pyramid.config import Configurator
0c29cf 117
804eb0 118         config = Configurator()
MM 119         manager = DummyThreadLocalManager()
120         req = object()
121         # set it up for auto-propagation
122         pushed = {'registry': config.registry, 'request': None}
123         manager.pushed = pushed
124         config.manager = manager
125         config.begin(req)
126         self.assertTrue(manager.pushed is not pushed)
127         self.assertEqual(manager.pushed['request'], req)
128         self.assertEqual(manager.pushed['registry'], config.registry)
129
130     def test_begin_propagates_request_for_same_registry(self):
131         from pyramid.config import Configurator
0c29cf 132
804eb0 133         config = Configurator()
MM 134         manager = DummyThreadLocalManager()
135         req = object()
136         pushed = {'registry': config.registry, 'request': req}
137         manager.pushed = pushed
138         config.manager = manager
139         config.begin()
140         self.assertTrue(manager.pushed is not pushed)
141         self.assertEqual(manager.pushed['request'], req)
142         self.assertEqual(manager.pushed['registry'], config.registry)
143
144     def test_begin_does_not_propagate_request_for_diff_registry(self):
145         from pyramid.config import Configurator
0c29cf 146
804eb0 147         config = Configurator()
MM 148         manager = DummyThreadLocalManager()
149         req = object()
150         pushed = {'registry': object(), 'request': req}
151         manager.pushed = pushed
152         config.manager = manager
153         config.begin()
154         self.assertTrue(manager.pushed is not pushed)
155         self.assertEqual(manager.pushed['request'], None)
156         self.assertEqual(manager.pushed['registry'], config.registry)
157
427a02 158     def test_end(self):
CM 159         from pyramid.config import Configurator
0c29cf 160
427a02 161         config = Configurator()
CM 162         manager = DummyThreadLocalManager()
804eb0 163         pushed = manager.pushed
427a02 164         config.manager = manager
CM 165         config.end()
804eb0 166         self.assertEqual(manager.pushed, pushed)
427a02 167         self.assertEqual(manager.popped, True)
CM 168
134ef7 169     def test_context_manager(self):
MM 170         from pyramid.config import Configurator
0c29cf 171
134ef7 172         config = Configurator()
MM 173         manager = DummyThreadLocalManager()
174         config.manager = manager
175         view = lambda r: None
176         with config as ctx:
177             self.assertTrue(config is ctx)
0c29cf 178             self.assertEqual(
MM 179                 manager.pushed, {'registry': config.registry, 'request': None}
180             )
134ef7 181             self.assertFalse(manager.popped)
MM 182             config.add_view(view)
183         self.assertTrue(manager.popped)
184         config.add_view(view)  # did not raise a conflict because of commit
185         config.commit()
186
427a02 187     def test_ctor_with_package_registry(self):
CM 188         import sys
189         from pyramid.config import Configurator
0c29cf 190
427a02 191         pkg = sys.modules['pyramid']
CM 192         config = Configurator(package=pkg)
193         self.assertEqual(config.package, pkg)
194
195     def test_ctor_noreg_custom_settings(self):
196         from pyramid.interfaces import ISettings
0c29cf 197
MM 198         settings = {'reload_templates': True, 'mysetting': True}
427a02 199         config = self._makeOne(settings=settings)
CM 200         settings = config.registry.getUtility(ISettings)
201         self.assertEqual(settings['reload_templates'], True)
202         self.assertEqual(settings['debug_authorization'], False)
203         self.assertEqual(settings['mysetting'], True)
204
205     def test_ctor_noreg_debug_logger_None_default(self):
206         from pyramid.interfaces import IDebugLogger
0c29cf 207
427a02 208         config = self._makeOne()
CM 209         logger = config.registry.getUtility(IDebugLogger)
dd3cc8 210         self.assertEqual(logger.name, 'tests.test_config')
427a02 211
CM 212     def test_ctor_noreg_debug_logger_non_None(self):
213         from pyramid.interfaces import IDebugLogger
0c29cf 214
427a02 215         logger = object()
CM 216         config = self._makeOne(debug_logger=logger)
217         result = config.registry.getUtility(IDebugLogger)
218         self.assertEqual(logger, result)
219
220     def test_ctor_authentication_policy(self):
221         from pyramid.interfaces import IAuthenticationPolicy
0c29cf 222
427a02 223         policy = object()
CM 224         config = self._makeOne(authentication_policy=policy)
381de3 225         config.commit()
427a02 226         result = config.registry.getUtility(IAuthenticationPolicy)
CM 227         self.assertEqual(policy, result)
228
229     def test_ctor_authorization_policy_only(self):
230         policy = object()
ea824f 231         config = self._makeOne(authorization_policy=policy)
CM 232         self.assertRaises(ConfigurationExecutionError, config.commit)
427a02 233
CM 234     def test_ctor_no_root_factory(self):
235         from pyramid.interfaces import IRootFactory
0c29cf 236
427a02 237         config = self._makeOne()
ea824f 238         self.assertEqual(config.registry.queryUtility(IRootFactory), None)
CM 239         config.commit()
2a818a 240         self.assertEqual(config.registry.queryUtility(IRootFactory), None)
CM 241
242     def test_ctor_with_root_factory(self):
243         from pyramid.interfaces import IRootFactory
0c29cf 244
2a818a 245         factory = object()
CM 246         config = self._makeOne(root_factory=factory)
247         self.assertEqual(config.registry.queryUtility(IRootFactory), None)
248         config.commit()
249         self.assertEqual(config.registry.queryUtility(IRootFactory), factory)
427a02 250
CM 251     def test_ctor_alternate_renderers(self):
252         from pyramid.interfaces import IRendererFactory
0c29cf 253
427a02 254         renderer = object()
CM 255         config = self._makeOne(renderers=[('yeah', renderer)])
381de3 256         config.commit()
0c29cf 257         self.assertEqual(
MM 258             config.registry.getUtility(IRendererFactory, 'yeah'), renderer
259         )
427a02 260
b93af9 261     def test_ctor_default_renderers(self):
CM 262         from pyramid.interfaces import IRendererFactory
263         from pyramid.renderers import json_renderer_factory
0c29cf 264
b93af9 265         config = self._makeOne()
0c29cf 266         self.assertEqual(
MM 267             config.registry.getUtility(IRendererFactory, 'json'),
268             json_renderer_factory,
269         )
b93af9 270
427a02 271     def test_ctor_default_permission(self):
CM 272         from pyramid.interfaces import IDefaultPermission
0c29cf 273
427a02 274         config = self._makeOne(default_permission='view')
f67ba4 275         config.commit()
0c29cf 276         self.assertEqual(
MM 277             config.registry.getUtility(IDefaultPermission), 'view'
278         )
427a02 279
CM 280     def test_ctor_session_factory(self):
281         from pyramid.interfaces import ISessionFactory
0c29cf 282
637bda 283         factory = object()
CM 284         config = self._makeOne(session_factory=factory)
ea824f 285         self.assertEqual(config.registry.queryUtility(ISessionFactory), None)
CM 286         config.commit()
637bda 287         self.assertEqual(config.registry.getUtility(ISessionFactory), factory)
80aa77 288
CM 289     def test_ctor_default_view_mapper(self):
290         from pyramid.interfaces import IViewMapperFactory
0c29cf 291
80aa77 292         mapper = object()
CM 293         config = self._makeOne(default_view_mapper=mapper)
381de3 294         config.commit()
0c29cf 295         self.assertEqual(
MM 296             config.registry.getUtility(IViewMapperFactory), mapper
297         )
427a02 298
1ffb8e 299     def test_ctor_httpexception_view_default(self):
8c2a9e 300         from pyramid.interfaces import IExceptionResponse
99edc5 301         from pyramid.httpexceptions import default_exceptionresponse_view
1ffb8e 302         from pyramid.interfaces import IRequest
0c29cf 303
1ffb8e 304         config = self._makeOne()
0c29cf 305         view = self._getViewCallable(
MM 306             config, ctx_iface=IExceptionResponse, request_iface=IRequest
307         )
58bc25 308         self.assertTrue(view.__wraps__ is default_exceptionresponse_view)
1ffb8e 309
8c2a9e 310     def test_ctor_exceptionresponse_view_None(self):
CM 311         from pyramid.interfaces import IExceptionResponse
1ffb8e 312         from pyramid.interfaces import IRequest
0c29cf 313
8c2a9e 314         config = self._makeOne(exceptionresponse_view=None)
0c29cf 315         view = self._getViewCallable(
MM 316             config, ctx_iface=IExceptionResponse, request_iface=IRequest
317         )
366a5c 318         self.assertTrue(view is None)
1ffb8e 319
8c2a9e 320     def test_ctor_exceptionresponse_view_custom(self):
CM 321         from pyramid.interfaces import IExceptionResponse
1ffb8e 322         from pyramid.interfaces import IRequest
0c29cf 323
10ddb6 324         def exceptionresponse_view(context, request):  # pragma: no cover
0c29cf 325             pass
MM 326
8c2a9e 327         config = self._makeOne(exceptionresponse_view=exceptionresponse_view)
0c29cf 328         view = self._getViewCallable(
MM 329             config, ctx_iface=IExceptionResponse, request_iface=IRequest
330         )
58bc25 331         self.assertTrue(view.__wraps__ is exceptionresponse_view)
1ffb8e 332
844ed9 333     def test_ctor_with_introspection(self):
CM 334         config = self._makeOne(introspection=False)
335         self.assertEqual(config.introspection, False)
2e651e 336
27190e 337     def test_ctor_default_webob_response_adapter_registered(self):
CM 338         from webob import Response as WebobResponse
0c29cf 339
27190e 340         response = WebobResponse()
CM 341         from pyramid.interfaces import IResponse
0c29cf 342
27190e 343         config = self._makeOne(autocommit=True)
CM 344         result = config.registry.queryAdapter(response, IResponse)
345         self.assertEqual(result, response)
0c29cf 346
427a02 347     def test_with_package_module(self):
dd3cc8 348         from . import test_init
0c29cf 349
427a02 350         config = self._makeOne()
1aeae3 351         newconfig = config.with_package(test_init)
dd3cc8 352         import tests.test_config
0c29cf 353
dd3cc8 354         self.assertEqual(newconfig.package, tests.test_config)
427a02 355
CM 356     def test_with_package_package(self):
dd3cc8 357         from tests import test_config
0c29cf 358
427a02 359         config = self._makeOne()
dd3cc8 360         newconfig = config.with_package(test_config)
MM 361         self.assertEqual(newconfig.package, test_config)
427a02 362
b86fa9 363     def test_with_package(self):
dd3cc8 364         import tests
0c29cf 365
865c1d 366         config = self._makeOne()
b86fa9 367         config.basepath = 'basepath'
CM 368         config.info = 'info'
369         config.includepath = ('spec',)
370         config.autocommit = True
371         config.route_prefix = 'prefix'
dd3cc8 372         newconfig = config.with_package(tests)
MM 373         self.assertEqual(newconfig.package, tests)
b86fa9 374         self.assertEqual(newconfig.registry, config.registry)
CM 375         self.assertEqual(newconfig.autocommit, True)
376         self.assertEqual(newconfig.route_prefix, 'prefix')
377         self.assertEqual(newconfig.info, 'info')
378         self.assertEqual(newconfig.basepath, 'basepath')
379         self.assertEqual(newconfig.includepath, ('spec',))
eb2a57 380
427a02 381     def test_maybe_dotted_string_success(self):
dd3cc8 382         import tests.test_config
0c29cf 383
427a02 384         config = self._makeOne()
dd3cc8 385         result = config.maybe_dotted('tests.test_config')
MM 386         self.assertEqual(result, tests.test_config)
427a02 387
CM 388     def test_maybe_dotted_string_fail(self):
389         config = self._makeOne()
79ef3d 390         self.assertRaises(ImportError, config.maybe_dotted, 'cant.be.found')
427a02 391
CM 392     def test_maybe_dotted_notstring_success(self):
dd3cc8 393         import tests.test_config
0c29cf 394
427a02 395         config = self._makeOne()
dd3cc8 396         result = config.maybe_dotted(tests.test_config)
MM 397         self.assertEqual(result, tests.test_config)
427a02 398
92c3e5 399     def test_absolute_asset_spec_already_absolute(self):
dd3cc8 400         import tests.test_config
0c29cf 401
dd3cc8 402         config = self._makeOne(package=tests.test_config)
92c3e5 403         result = config.absolute_asset_spec('already:absolute')
427a02 404         self.assertEqual(result, 'already:absolute')
CM 405
92c3e5 406     def test_absolute_asset_spec_notastring(self):
dd3cc8 407         import tests.test_config
0c29cf 408
dd3cc8 409         config = self._makeOne(package=tests.test_config)
92c3e5 410         result = config.absolute_asset_spec(None)
427a02 411         self.assertEqual(result, None)
CM 412
92c3e5 413     def test_absolute_asset_spec_relative(self):
dd3cc8 414         import tests.test_config
0c29cf 415
dd3cc8 416         config = self._makeOne(package=tests.test_config)
1aeae3 417         result = config.absolute_asset_spec('files')
dd3cc8 418         self.assertEqual(result, 'tests.test_config:files')
427a02 419
d868ff 420     def test__fix_registry_has_listeners(self):
CM 421         reg = DummyRegistry()
422         config = self._makeOne(reg)
423         config._fix_registry()
424         self.assertEqual(reg.has_listeners, True)
425
426     def test__fix_registry_notify(self):
427         reg = DummyRegistry()
428         config = self._makeOne(reg)
429         config._fix_registry()
430         self.assertEqual(reg.notify(1), None)
431         self.assertEqual(reg.events, (1,))
432
433     def test__fix_registry_queryAdapterOrSelf(self):
434         from zope.interface import Interface
3b7334 435         from zope.interface import implementer
0c29cf 436
d868ff 437         class IFoo(Interface):
CM 438             pass
0c29cf 439
3b7334 440         @implementer(IFoo)
d868ff 441         class Foo(object):
3b7334 442             pass
0c29cf 443
d868ff 444         class Bar(object):
CM 445             pass
0c29cf 446
d868ff 447         adaptation = ()
CM 448         foo = Foo()
449         bar = Bar()
450         reg = DummyRegistry(adaptation)
451         config = self._makeOne(reg)
452         config._fix_registry()
453         self.assertTrue(reg.queryAdapterOrSelf(foo, IFoo) is foo)
454         self.assertTrue(reg.queryAdapterOrSelf(bar, IFoo) is adaptation)
455
456     def test__fix_registry_registerSelfAdapter(self):
457         reg = DummyRegistry()
458         config = self._makeOne(reg)
459         config._fix_registry()
460         reg.registerSelfAdapter('required', 'provided', name='abc')
461         self.assertEqual(len(reg.adapters), 1)
462         args, kw = reg.adapters[0]
463         self.assertEqual(args[0]('abc'), 'abc')
0c29cf 464         self.assertEqual(
MM 465             kw,
466             {
467                 'info': '',
468                 'provided': 'provided',
469                 'required': 'required',
470                 'name': 'abc',
471                 'event': True,
472             },
473         )
d868ff 474
c15cbc 475     def test__fix_registry_adds__lock(self):
CM 476         reg = DummyRegistry()
477         config = self._makeOne(reg)
478         config._fix_registry()
479         self.assertTrue(hasattr(reg, '_lock'))
480
481     def test__fix_registry_adds_clear_view_lookup_cache(self):
482         reg = DummyRegistry()
483         config = self._makeOne(reg)
484         self.assertFalse(hasattr(reg, '_clear_view_lookup_cache'))
485         config._fix_registry()
486         self.assertFalse(hasattr(reg, '_view_lookup_cache'))
487         reg._clear_view_lookup_cache()
488         self.assertEqual(reg._view_lookup_cache, {})
489
d868ff 490     def test_setup_registry_calls_fix_registry(self):
427a02 491         reg = DummyRegistry()
CM 492         config = self._makeOne(reg)
493         config.add_view = lambda *arg, **kw: False
b4843b 494         config._add_tween = lambda *arg, **kw: False
427a02 495         config.setup_registry()
CM 496         self.assertEqual(reg.has_listeners, True)
497
a00621 498     def test_setup_registry_registers_default_exceptionresponse_views(self):
d69ae6 499         from webob.exc import WSGIHTTPException
427a02 500         from pyramid.interfaces import IExceptionResponse
CM 501         from pyramid.view import default_exceptionresponse_view
0c29cf 502
427a02 503         reg = DummyRegistry()
CM 504         config = self._makeOne(reg)
505         views = []
506         config.add_view = lambda *arg, **kw: views.append((arg, kw))
a00621 507         config.add_default_view_predicates = lambda *arg: None
b4843b 508         config._add_tween = lambda *arg, **kw: False
427a02 509         config.setup_registry()
0c29cf 510         self.assertEqual(
MM 511             views[0],
512             (
513                 (default_exceptionresponse_view,),
514                 {'context': IExceptionResponse},
515             ),
516         )
517         self.assertEqual(
518             views[1],
519             (
520                 (default_exceptionresponse_view,),
521                 {'context': WSGIHTTPException},
522             ),
523         )
a00621 524
CM 525     def test_setup_registry_registers_default_view_predicates(self):
526         reg = DummyRegistry()
527         config = self._makeOne(reg)
528         vp_called = []
529         config.add_view = lambda *arg, **kw: None
0c29cf 530         config.add_default_view_predicates = lambda *arg: vp_called.append(
MM 531             True
532         )
a00621 533         config._add_tween = lambda *arg, **kw: False
CM 534         config.setup_registry()
535         self.assertTrue(vp_called)
d868ff 536
CM 537     def test_setup_registry_registers_default_webob_iresponse_adapter(self):
538         from webob import Response
539         from pyramid.interfaces import IResponse
0c29cf 540
d868ff 541         config = self._makeOne()
CM 542         config.setup_registry()
543         response = Response()
544         self.assertTrue(
0c29cf 545             config.registry.queryAdapter(response, IResponse) is response
MM 546         )
1ffb8e 547
427a02 548     def test_setup_registry_explicit_notfound_trumps_iexceptionresponse(self):
aa2fe1 549         from pyramid.renderers import null_renderer
427a02 550         from zope.interface import implementedBy
CM 551         from pyramid.interfaces import IRequest
99edc5 552         from pyramid.httpexceptions import HTTPNotFound
427a02 553         from pyramid.registry import Registry
0c29cf 554
427a02 555         reg = Registry()
CM 556         config = self._makeOne(reg, autocommit=True)
0c29cf 557         config.setup_registry()  # registers IExceptionResponse default view
MM 558
427a02 559         def myview(context, request):
CM 560             return 'OK'
0c29cf 561
aa2fe1 562         config.add_view(myview, context=HTTPNotFound, renderer=null_renderer)
427a02 563         request = self._makeRequest(config)
0c29cf 564         view = self._getViewCallable(
MM 565             config,
566             ctx_iface=implementedBy(HTTPNotFound),
567             request_iface=IRequest,
568         )
427a02 569         result = view(None, request)
CM 570         self.assertEqual(result, 'OK')
571
572     def test_setup_registry_custom_settings(self):
573         from pyramid.registry import Registry
574         from pyramid.interfaces import ISettings
0c29cf 575
MM 576         settings = {'reload_templates': True, 'mysetting': True}
427a02 577         reg = Registry()
CM 578         config = self._makeOne(reg)
579         config.setup_registry(settings=settings)
580         settings = reg.getUtility(ISettings)
581         self.assertEqual(settings['reload_templates'], True)
582         self.assertEqual(settings['debug_authorization'], False)
583         self.assertEqual(settings['mysetting'], True)
584
585     def test_setup_registry_debug_logger_None_default(self):
586         from pyramid.registry import Registry
587         from pyramid.interfaces import IDebugLogger
0c29cf 588
427a02 589         reg = Registry()
CM 590         config = self._makeOne(reg)
591         config.setup_registry()
592         logger = reg.getUtility(IDebugLogger)
dd3cc8 593         self.assertEqual(logger.name, 'tests.test_config')
427a02 594
CM 595     def test_setup_registry_debug_logger_non_None(self):
596         from pyramid.registry import Registry
597         from pyramid.interfaces import IDebugLogger
0c29cf 598
427a02 599         logger = object()
CM 600         reg = Registry()
601         config = self._makeOne(reg)
602         config.setup_registry(debug_logger=logger)
603         result = reg.getUtility(IDebugLogger)
604         self.assertEqual(logger, result)
605
3a8054 606     def test_setup_registry_debug_logger_name(self):
427a02 607         from pyramid.registry import Registry
CM 608         from pyramid.interfaces import IDebugLogger
0c29cf 609
427a02 610         reg = Registry()
CM 611         config = self._makeOne(reg)
3a8054 612         config.setup_registry(debug_logger='foo')
427a02 613         result = reg.getUtility(IDebugLogger)
3a8054 614         self.assertEqual(result.name, 'foo')
427a02 615
CM 616     def test_setup_registry_authentication_policy(self):
617         from pyramid.registry import Registry
618         from pyramid.interfaces import IAuthenticationPolicy
0c29cf 619
427a02 620         policy = object()
CM 621         reg = Registry()
622         config = self._makeOne(reg)
623         config.setup_registry(authentication_policy=policy)
f67ba4 624         config.commit()
427a02 625         result = reg.getUtility(IAuthenticationPolicy)
CM 626         self.assertEqual(policy, result)
627
628     def test_setup_registry_authentication_policy_dottedname(self):
629         from pyramid.registry import Registry
630         from pyramid.interfaces import IAuthenticationPolicy
0c29cf 631
427a02 632         reg = Registry()
CM 633         config = self._makeOne(reg)
dd3cc8 634         config.setup_registry(authentication_policy='tests.test_config')
f67ba4 635         config.commit()
427a02 636         result = reg.getUtility(IAuthenticationPolicy)
dd3cc8 637         import tests.test_config
0c29cf 638
dd3cc8 639         self.assertEqual(result, tests.test_config)
427a02 640
CM 641     def test_setup_registry_authorization_policy_dottedname(self):
642         from pyramid.registry import Registry
643         from pyramid.interfaces import IAuthorizationPolicy
0c29cf 644
427a02 645         reg = Registry()
CM 646         config = self._makeOne(reg)
647         dummy = object()
0c29cf 648         config.setup_registry(
MM 649             authentication_policy=dummy,
650             authorization_policy='tests.test_config',
651         )
f67ba4 652         config.commit()
427a02 653         result = reg.getUtility(IAuthorizationPolicy)
dd3cc8 654         import tests.test_config
0c29cf 655
dd3cc8 656         self.assertEqual(result, tests.test_config)
427a02 657
CM 658     def test_setup_registry_authorization_policy_only(self):
659         from pyramid.registry import Registry
0c29cf 660
427a02 661         policy = object()
CM 662         reg = Registry()
663         config = self._makeOne(reg)
ea824f 664         config.setup_registry(authorization_policy=policy)
CM 665         config = self.assertRaises(ConfigurationExecutionError, config.commit)
427a02 666
2a818a 667     def test_setup_registry_no_default_root_factory(self):
427a02 668         from pyramid.registry import Registry
CM 669         from pyramid.interfaces import IRootFactory
0c29cf 670
427a02 671         reg = Registry()
CM 672         config = self._makeOne(reg)
673         config.setup_registry()
ea824f 674         config.commit()
2a818a 675         self.assertEqual(reg.queryUtility(IRootFactory), None)
427a02 676
CM 677     def test_setup_registry_dottedname_root_factory(self):
678         from pyramid.registry import Registry
679         from pyramid.interfaces import IRootFactory
0c29cf 680
427a02 681         reg = Registry()
CM 682         config = self._makeOne(reg)
dd3cc8 683         import tests.test_config
0c29cf 684
dd3cc8 685         config.setup_registry(root_factory='tests.test_config')
ea824f 686         self.assertEqual(reg.queryUtility(IRootFactory), None)
CM 687         config.commit()
dd3cc8 688         self.assertEqual(reg.getUtility(IRootFactory), tests.test_config)
427a02 689
CM 690     def test_setup_registry_locale_negotiator_dottedname(self):
691         from pyramid.registry import Registry
692         from pyramid.interfaces import ILocaleNegotiator
0c29cf 693
427a02 694         reg = Registry()
CM 695         config = self._makeOne(reg)
dd3cc8 696         import tests.test_config
0c29cf 697
dd3cc8 698         config.setup_registry(locale_negotiator='tests.test_config')
ea824f 699         self.assertEqual(reg.queryUtility(ILocaleNegotiator), None)
CM 700         config.commit()
427a02 701         utility = reg.getUtility(ILocaleNegotiator)
dd3cc8 702         self.assertEqual(utility, tests.test_config)
427a02 703
CM 704     def test_setup_registry_locale_negotiator(self):
705         from pyramid.registry import Registry
706         from pyramid.interfaces import ILocaleNegotiator
0c29cf 707
427a02 708         reg = Registry()
CM 709         config = self._makeOne(reg)
710         negotiator = object()
711         config.setup_registry(locale_negotiator=negotiator)
ea824f 712         self.assertEqual(reg.queryUtility(ILocaleNegotiator), None)
CM 713         config.commit()
427a02 714         utility = reg.getUtility(ILocaleNegotiator)
CM 715         self.assertEqual(utility, negotiator)
716
717     def test_setup_registry_request_factory(self):
718         from pyramid.registry import Registry
719         from pyramid.interfaces import IRequestFactory
0c29cf 720
427a02 721         reg = Registry()
CM 722         config = self._makeOne(reg)
723         factory = object()
724         config.setup_registry(request_factory=factory)
ea824f 725         self.assertEqual(reg.queryUtility(IRequestFactory), None)
CM 726         config.commit()
427a02 727         utility = reg.getUtility(IRequestFactory)
CM 728         self.assertEqual(utility, factory)
729
1236de 730     def test_setup_registry_response_factory(self):
JA 731         from pyramid.registry import Registry
732         from pyramid.interfaces import IResponseFactory
0c29cf 733
1236de 734         reg = Registry()
JA 735         config = self._makeOne(reg)
32cb80 736         factory = lambda r: object()
1236de 737         config.setup_registry(response_factory=factory)
JA 738         self.assertEqual(reg.queryUtility(IResponseFactory), None)
739         config.commit()
740         utility = reg.getUtility(IResponseFactory)
741         self.assertEqual(utility, factory)
367ffe 742
427a02 743     def test_setup_registry_request_factory_dottedname(self):
CM 744         from pyramid.registry import Registry
745         from pyramid.interfaces import IRequestFactory
0c29cf 746
427a02 747         reg = Registry()
CM 748         config = self._makeOne(reg)
dd3cc8 749         import tests.test_config
0c29cf 750
dd3cc8 751         config.setup_registry(request_factory='tests.test_config')
ea824f 752         self.assertEqual(reg.queryUtility(IRequestFactory), None)
CM 753         config.commit()
427a02 754         utility = reg.getUtility(IRequestFactory)
dd3cc8 755         self.assertEqual(utility, tests.test_config)
427a02 756
CM 757     def test_setup_registry_alternate_renderers(self):
758         from pyramid.registry import Registry
759         from pyramid.interfaces import IRendererFactory
0c29cf 760
427a02 761         renderer = object()
CM 762         reg = Registry()
763         config = self._makeOne(reg)
764         config.setup_registry(renderers=[('yeah', renderer)])
f67ba4 765         config.commit()
0c29cf 766         self.assertEqual(reg.getUtility(IRendererFactory, 'yeah'), renderer)
427a02 767
CM 768     def test_setup_registry_default_permission(self):
769         from pyramid.registry import Registry
770         from pyramid.interfaces import IDefaultPermission
0c29cf 771
427a02 772         reg = Registry()
CM 773         config = self._makeOne(reg)
774         config.setup_registry(default_permission='view')
f67ba4 775         config.commit()
427a02 776         self.assertEqual(reg.getUtility(IDefaultPermission), 'view')
CM 777
1a45b4 778     def test_setup_registry_includes(self):
MM 779         from pyramid.registry import Registry
0c29cf 780
1a45b4 781         reg = Registry()
MM 782         config = self._makeOne(reg)
783         settings = {
0c29cf 784             'pyramid.includes': """tests.test_config.dummy_include
MM 785 tests.test_config.dummy_include2"""
1a45b4 786         }
MM 787         config.setup_registry(settings=settings)
fd266a 788         self.assertTrue(reg.included)
CM 789         self.assertTrue(reg.also_included)
1a45b4 790
8cd013 791     def test_setup_registry_includes_spaces(self):
CM 792         from pyramid.registry import Registry
0c29cf 793
8cd013 794         reg = Registry()
CM 795         config = self._makeOne(reg)
796         settings = {
10ddb6 797             'pyramid.includes': """tests.test_config.dummy_include tests.\
MM 798 test_config.dummy_include2"""
8cd013 799         }
CM 800         config.setup_registry(settings=settings)
fd266a 801         self.assertTrue(reg.included)
CM 802         self.assertTrue(reg.also_included)
8cd013 803
feabd3 804     def test_setup_registry_tweens(self):
CM 805         from pyramid.interfaces import ITweens
806         from pyramid.registry import Registry
0c29cf 807
feabd3 808         reg = Registry()
CM 809         config = self._makeOne(reg)
0c29cf 810         settings = {'pyramid.tweens': 'tests.test_config.dummy_tween_factory'}
feabd3 811         config.setup_registry(settings=settings)
8517d4 812         config.commit()
feabd3 813         tweens = config.registry.getUtility(ITweens)
5bf23f 814         self.assertEqual(
CM 815             tweens.explicit,
0c29cf 816             [('tests.test_config.dummy_tween_factory', dummy_tween_factory)],
MM 817         )
feabd3 818
2e651e 819     def test_introspector_decorator(self):
CM 820         inst = self._makeOne()
821         default = inst.introspector
4e6afc 822         self.assertTrue(hasattr(default, 'add'))
2e651e 823         self.assertEqual(inst.introspector, inst.registry.introspector)
844ed9 824         introspector = object()
2e651e 825         inst.introspector = introspector
CM 826         new = inst.introspector
4e6afc 827         self.assertTrue(new is introspector)
2e651e 828         self.assertEqual(inst.introspector, inst.registry.introspector)
CM 829         del inst.introspector
830         default = inst.introspector
4e6afc 831         self.assertFalse(default is new)
CM 832         self.assertTrue(hasattr(default, 'add'))
2e651e 833
427a02 834     def test_make_wsgi_app(self):
68d12c 835         import pyramid.config
427a02 836         from pyramid.router import Router
CM 837         from pyramid.interfaces import IApplicationCreated
0c29cf 838
427a02 839         manager = DummyThreadLocalManager()
CM 840         config = self._makeOne()
841         subscriber = self._registerEventListener(config, IApplicationCreated)
842         config.manager = manager
843         app = config.make_wsgi_app()
844         self.assertEqual(app.__class__, Router)
845         self.assertEqual(manager.pushed['registry'], config.registry)
846         self.assertEqual(manager.pushed['request'], None)
a1d395 847         self.assertTrue(manager.popped)
981c05 848         self.assertEqual(pyramid.config.global_registries.last, app.registry)
427a02 849         self.assertEqual(len(subscriber), 1)
a1d395 850         self.assertTrue(IApplicationCreated.providedBy(subscriber[0]))
eff1cb 851         pyramid.config.global_registries.empty()
427a02 852
CM 853     def test_include_with_dotted_name(self):
dd3cc8 854         from tests import test_config
0c29cf 855
427a02 856         config = self._makeOne()
dd3cc8 857         config.include('tests.test_config.dummy_include')
b86fa9 858         after = config.action_state
CM 859         actions = after.actions
427a02 860         self.assertEqual(len(actions), 1)
412b4a 861         action = after.actions[0]
CM 862         self.assertEqual(action['discriminator'], 'discrim')
863         self.assertEqual(action['callable'], None)
864         self.assertEqual(action['args'], test_config)
427a02 865
CM 866     def test_include_with_python_callable(self):
dd3cc8 867         from tests import test_config
0c29cf 868
427a02 869         config = self._makeOne()
CM 870         config.include(dummy_include)
b86fa9 871         after = config.action_state
CM 872         actions = after.actions
427a02 873         self.assertEqual(len(actions), 1)
412b4a 874         action = actions[0]
CM 875         self.assertEqual(action['discriminator'], 'discrim')
876         self.assertEqual(action['callable'], None)
877         self.assertEqual(action['args'], test_config)
427a02 878
08170a 879     def test_include_with_module_defaults_to_includeme(self):
dd3cc8 880         from tests import test_config
0c29cf 881
08170a 882         config = self._makeOne()
dd3cc8 883         config.include('tests.test_config')
b86fa9 884         after = config.action_state
CM 885         actions = after.actions
08170a 886         self.assertEqual(len(actions), 1)
412b4a 887         action = actions[0]
CM 888         self.assertEqual(action['discriminator'], 'discrim')
889         self.assertEqual(action['callable'], None)
890         self.assertEqual(action['args'], test_config)
0b13e1 891
f8bfc6 892     def test_include_with_module_defaults_to_includeme_missing(self):
CM 893         from pyramid.exceptions import ConfigurationError
0c29cf 894
f8bfc6 895         config = self._makeOne()
dd3cc8 896         self.assertRaises(ConfigurationError, config.include, 'tests')
f8bfc6 897
0b13e1 898     def test_include_with_route_prefix(self):
MM 899         root_config = self._makeOne(autocommit=True)
0c29cf 900
0b13e1 901         def dummy_subapp(config):
MM 902             self.assertEqual(config.route_prefix, 'root')
0c29cf 903
0b13e1 904         root_config.include(dummy_subapp, route_prefix='root')
MM 905
906     def test_include_with_nested_route_prefix(self):
907         root_config = self._makeOne(autocommit=True, route_prefix='root')
0c29cf 908
7a7c8c 909         def dummy_subapp2(config):
CM 910             self.assertEqual(config.route_prefix, 'root/nested')
0c29cf 911
7a7c8c 912         def dummy_subapp3(config):
CM 913             self.assertEqual(config.route_prefix, 'root/nested/nested2')
914             config.include(dummy_subapp4)
0c29cf 915
7a7c8c 916         def dummy_subapp4(config):
CM 917             self.assertEqual(config.route_prefix, 'root/nested/nested2')
0c29cf 918
0b13e1 919         def dummy_subapp(config):
MM 920             self.assertEqual(config.route_prefix, 'root/nested')
7a7c8c 921             config.include(dummy_subapp2)
CM 922             config.include(dummy_subapp3, route_prefix='nested2')
923
0b13e1 924         root_config.include(dummy_subapp, route_prefix='nested')
08170a 925
5ad401 926     def test_include_with_missing_source_file(self):
CM 927         from pyramid.exceptions import ConfigurationError
928         import inspect
0c29cf 929
5ad401 930         config = self._makeOne()
0c29cf 931
5ad401 932         class DummyInspect(object):
CM 933             def getmodule(self, c):
934                 return inspect.getmodule(c)
0c29cf 935
5ad401 936             def getsourcefile(self, c):
CM 937                 return None
0c29cf 938
5ad401 939         config.inspect = DummyInspect()
CM 940         try:
dd3cc8 941             config.include('tests.test_config.dummy_include')
5ad401 942         except ConfigurationError as e:
CM 943             self.assertEqual(
0c29cf 944                 e.args[0],
dd3cc8 945                 "No source file for module 'tests.test_config' (.py "
0c29cf 946                 "file must exist, refusing to use orphan .pyc or .pyo file).",
MM 947             )
948         else:  # pragma: no cover
5ad401 949             raise AssertionError
f5bafd 950
ae6c88 951     def test_include_constant_root_package(self):
dd3cc8 952         import tests
MM 953         from tests import test_config
0c29cf 954
ae6c88 955         config = self._makeOne(root_package=tests)
MM 956         results = {}
0c29cf 957
ae6c88 958         def include(config):
MM 959             results['package'] = config.package
960             results['root_package'] = config.root_package
0c29cf 961
ae6c88 962         config.include(include)
MM 963         self.assertEqual(results['root_package'], tests)
964         self.assertEqual(results['package'], test_config)
965
a857eb 966     def test_include_threadlocals_active(self):
MM 967         from pyramid.threadlocal import get_current_registry
0c29cf 968
a857eb 969         stack = []
0c29cf 970
a857eb 971         def include(config):
MM 972             stack.append(get_current_registry())
0c29cf 973
a857eb 974         config = self._makeOne()
MM 975         config.include(include)
976         self.assertTrue(stack[0] is config.registry)
977
6c9090 978     def test_action_branching_kw_is_None(self):
CM 979         config = self._makeOne(autocommit=True)
980         self.assertEqual(config.action('discrim'), None)
981
982     def test_action_branching_kw_is_not_None(self):
983         config = self._makeOne(autocommit=True)
0c29cf 984         self.assertEqual(config.action('discrim', kw={'a': 1}), None)
6c9090 985
2e651e 986     def test_action_autocommit_with_introspectables(self):
52fde9 987         from pyramid.config.util import ActionInfo
0c29cf 988
2e651e 989         config = self._makeOne(autocommit=True)
CM 990         intr = DummyIntrospectable()
991         config.action('discrim', introspectables=(intr,))
992         self.assertEqual(len(intr.registered), 1)
993         self.assertEqual(intr.registered[0][0], config.introspector)
994         self.assertEqual(intr.registered[0][1].__class__, ActionInfo)
995
0192b5 996     def test_action_autocommit_with_introspectables_introspection_off(self):
CM 997         config = self._makeOne(autocommit=True)
998         config.introspection = False
999         intr = DummyIntrospectable()
1000         config.action('discrim', introspectables=(intr,))
1001         self.assertEqual(len(intr.registered), 0)
0c29cf 1002
b86fa9 1003     def test_action_branching_nonautocommit_with_config_info(self):
6c9090 1004         config = self._makeOne(autocommit=False)
b86fa9 1005         config.info = 'abc'
940ab0 1006         state = DummyActionState()
CM 1007         state.autocommit = False
b86fa9 1008         config.action_state = state
0c29cf 1009         config.action('discrim', kw={'a': 1})
940ab0 1010         self.assertEqual(
CM 1011             state.actions,
0c29cf 1012             [
MM 1013                 (
1014                     (),
1015                     {
1016                         'args': (),
1017                         'callable': None,
1018                         'discriminator': 'discrim',
1019                         'includepath': (),
1020                         'info': 'abc',
1021                         'introspectables': (),
1022                         'kw': {'a': 1},
1023                         'order': 0,
1024                     },
1025                 )
1026             ],
1027         )
940ab0 1028
b86fa9 1029     def test_action_branching_nonautocommit_without_config_info(self):
940ab0 1030         config = self._makeOne(autocommit=False)
b86fa9 1031         config.info = ''
940ab0 1032         config._ainfo = ['z']
b86fa9 1033         state = DummyActionState()
CM 1034         config.action_state = state
1035         state.autocommit = False
0c29cf 1036         config.action('discrim', kw={'a': 1})
940ab0 1037         self.assertEqual(
CM 1038             state.actions,
0c29cf 1039             [
MM 1040                 (
1041                     (),
1042                     {
1043                         'args': (),
1044                         'callable': None,
1045                         'discriminator': 'discrim',
1046                         'includepath': (),
1047                         'info': 'z',
1048                         'introspectables': (),
1049                         'kw': {'a': 1},
1050                         'order': 0,
1051                     },
1052                 )
1053             ],
1054         )
2e651e 1055
CM 1056     def test_action_branching_nonautocommit_with_introspectables(self):
1057         config = self._makeOne(autocommit=False)
1058         config.info = ''
1059         config._ainfo = []
1060         state = DummyActionState()
1061         config.action_state = state
1062         state.autocommit = False
1063         intr = DummyIntrospectable()
1064         config.action('discrim', introspectables=(intr,))
0c29cf 1065         self.assertEqual(state.actions[0][1]['introspectables'], (intr,))
6c9090 1066
0192b5 1067     def test_action_nonautocommit_with_introspectables_introspection_off(self):
CM 1068         config = self._makeOne(autocommit=False)
1069         config.info = ''
1070         config._ainfo = []
1071         config.introspection = False
1072         state = DummyActionState()
1073         config.action_state = state
1074         state.autocommit = False
1075         intr = DummyIntrospectable()
1076         config.action('discrim', introspectables=(intr,))
0c29cf 1077         self.assertEqual(state.actions[0][1]['introspectables'], ())
MM 1078
427a02 1079     def test_scan_integration(self):
CM 1080         from zope.interface import alsoProvides
1081         from pyramid.interfaces import IRequest
1082         from pyramid.view import render_view_to_response
dd3cc8 1083         import tests.test_config.pkgs.scannable as package
0c29cf 1084
427a02 1085         config = self._makeOne(autocommit=True)
CM 1086         config.scan(package)
1087
1088         ctx = DummyContext()
1089         req = DummyRequest()
1090         alsoProvides(req, IRequest)
1091         req.registry = config.registry
1092
1093         req.method = 'GET'
1094         result = render_view_to_response(ctx, req, '')
1095         self.assertEqual(result, 'grokked')
1096
1097         req.method = 'POST'
1098         result = render_view_to_response(ctx, req, '')
1099         self.assertEqual(result, 'grokked_post')
1100
0c29cf 1101         result = render_view_to_response(ctx, req, 'grokked_class')
427a02 1102         self.assertEqual(result, 'grokked_class')
CM 1103
0c29cf 1104         result = render_view_to_response(ctx, req, 'grokked_instance')
427a02 1105         self.assertEqual(result, 'grokked_instance')
CM 1106
0c29cf 1107         result = render_view_to_response(ctx, req, 'oldstyle_grokked_class')
427a02 1108         self.assertEqual(result, 'oldstyle_grokked_class')
CM 1109
1110         req.method = 'GET'
1111         result = render_view_to_response(ctx, req, 'another')
1112         self.assertEqual(result, 'another_grokked')
1113
1114         req.method = 'POST'
1115         result = render_view_to_response(ctx, req, 'another')
1116         self.assertEqual(result, 'another_grokked_post')
1117
0c29cf 1118         result = render_view_to_response(ctx, req, 'another_grokked_class')
427a02 1119         self.assertEqual(result, 'another_grokked_class')
CM 1120
0c29cf 1121         result = render_view_to_response(ctx, req, 'another_grokked_instance')
427a02 1122         self.assertEqual(result, 'another_grokked_instance')
CM 1123
0c29cf 1124         result = render_view_to_response(
MM 1125             ctx, req, 'another_oldstyle_grokked_class'
1126         )
427a02 1127         self.assertEqual(result, 'another_oldstyle_grokked_class')
CM 1128
1129         result = render_view_to_response(ctx, req, 'stacked1')
1130         self.assertEqual(result, 'stacked')
1131
1132         result = render_view_to_response(ctx, req, 'stacked2')
1133         self.assertEqual(result, 'stacked')
1134
1135         result = render_view_to_response(ctx, req, 'another_stacked1')
1136         self.assertEqual(result, 'another_stacked')
1137
1138         result = render_view_to_response(ctx, req, 'another_stacked2')
1139         self.assertEqual(result, 'another_stacked')
1140
1141         result = render_view_to_response(ctx, req, 'stacked_class1')
1142         self.assertEqual(result, 'stacked_class')
1143
1144         result = render_view_to_response(ctx, req, 'stacked_class2')
1145         self.assertEqual(result, 'stacked_class')
1146
1147         result = render_view_to_response(ctx, req, 'another_stacked_class1')
1148         self.assertEqual(result, 'another_stacked_class')
1149
1150         result = render_view_to_response(ctx, req, 'another_stacked_class2')
1151         self.assertEqual(result, 'another_stacked_class')
1152
1c7724 1153         # NB: on Jython, a class without an __init__ apparently accepts
CM 1154         # any number of arguments without raising a TypeError, so the next
1155         # assertion may fail there.  We don't support Jython at the moment,
1156         # this is just a note to a future self.
427a02 1157
0c29cf 1158         self.assertRaises(
MM 1159             TypeError, render_view_to_response, ctx, req, 'basemethod'
1160         )
427a02 1161
CM 1162         result = render_view_to_response(ctx, req, 'method1')
1163         self.assertEqual(result, 'method1')
1164
1165         result = render_view_to_response(ctx, req, 'method2')
1166         self.assertEqual(result, 'method2')
1167
1168         result = render_view_to_response(ctx, req, 'stacked_method1')
1169         self.assertEqual(result, 'stacked_method')
1170
1171         result = render_view_to_response(ctx, req, 'stacked_method2')
1172         self.assertEqual(result, 'stacked_method')
1173
1174         result = render_view_to_response(ctx, req, 'subpackage_init')
1175         self.assertEqual(result, 'subpackage_init')
1176
1177         result = render_view_to_response(ctx, req, 'subpackage_notinit')
1178         self.assertEqual(result, 'subpackage_notinit')
1179
1180         result = render_view_to_response(ctx, req, 'subsubpackage_init')
1181         self.assertEqual(result, 'subsubpackage_init')
1182
1183         result = render_view_to_response(ctx, req, 'pod_notinit')
1184         self.assertEqual(result, None)
1185
e4b8fa 1186     def test_scan_integration_with_ignore(self):
CM 1187         from zope.interface import alsoProvides
1188         from pyramid.interfaces import IRequest
1189         from pyramid.view import render_view_to_response
dd3cc8 1190         import tests.test_config.pkgs.scannable as package
0c29cf 1191
e4b8fa 1192         config = self._makeOne(autocommit=True)
0c29cf 1193         config.scan(package, ignore='tests.test_config.pkgs.scannable.another')
e4b8fa 1194
CM 1195         ctx = DummyContext()
1196         req = DummyRequest()
1197         alsoProvides(req, IRequest)
1198         req.registry = config.registry
1199
1200         req.method = 'GET'
1201         result = render_view_to_response(ctx, req, '')
1202         self.assertEqual(result, 'grokked')
1203
1204         # ignored
1205         v = render_view_to_response(ctx, req, 'another_stacked_class2')
1206         self.assertEqual(v, None)
0c29cf 1207
427a02 1208     def test_scan_integration_dottedname_package(self):
CM 1209         from zope.interface import alsoProvides
1210         from pyramid.interfaces import IRequest
1211         from pyramid.view import render_view_to_response
0c29cf 1212
427a02 1213         config = self._makeOne(autocommit=True)
dd3cc8 1214         config.scan('tests.test_config.pkgs.scannable')
427a02 1215
CM 1216         ctx = DummyContext()
1217         req = DummyRequest()
1218         alsoProvides(req, IRequest)
1219         req.registry = config.registry
1220
1221         req.method = 'GET'
1222         result = render_view_to_response(ctx, req, '')
1223         self.assertEqual(result, 'grokked')
1224
fca1ef 1225     def test_scan_integration_with_extra_kw(self):
CM 1226         config = self._makeOne(autocommit=True)
dd3cc8 1227         config.scan('tests.test_config.pkgs.scanextrakw', a=1)
fca1ef 1228         self.assertEqual(config.a, 1)
1aeae3 1229
CM 1230     def test_scan_integration_with_onerror(self):
1231         # fancy sys.path manipulation here to appease "setup.py test" which
1232         # fails miserably when it can't import something in the package
1233         import sys
0c29cf 1234
1aeae3 1235         try:
CM 1236             here = os.path.dirname(__file__)
1237             path = os.path.join(here, 'path')
1238             sys.path.append(path)
1239             config = self._makeOne(autocommit=True)
0c29cf 1240
1aeae3 1241             class FooException(Exception):
CM 1242                 pass
0c29cf 1243
1aeae3 1244             def onerror(name):
CM 1245                 raise FooException
0c29cf 1246
MM 1247             self.assertRaises(
1248                 FooException, config.scan, 'scanerror', onerror=onerror
1249             )
1aeae3 1250         finally:
CM 1251             sys.path.remove(path)
1252
1253     def test_scan_integration_conflict(self):
dd3cc8 1254         from tests.test_config.pkgs import selfscan
1aeae3 1255         from pyramid.config import Configurator
0c29cf 1256
1aeae3 1257         c = Configurator()
CM 1258         c.scan(selfscan)
1259         c.scan(selfscan)
1260         try:
1261             c.commit()
8e606d 1262         except ConfigurationConflictError as why:
0c29cf 1263
1aeae3 1264             def scanconflicts(e):
CM 1265                 conflicts = e._conflicts.values()
1266                 for conflict in conflicts:
1267                     for confinst in conflict:
4a4ef4 1268                         yield confinst.src
0c29cf 1269
1aeae3 1270             which = list(scanconflicts(why))
CM 1271             self.assertEqual(len(which), 4)
1272             self.assertTrue("@view_config(renderer='string')" in which)
0c29cf 1273             self.assertTrue(
MM 1274                 "@view_config(name='two', renderer='string')" in which
1275             )
1aeae3 1276
fbd01a 1277     @skip_on('py3')
427a02 1278     def test_hook_zca(self):
865c1d 1279         from zope.component import getSiteManager
0c29cf 1280
865c1d 1281         def foo():
CM 1282             '123'
0c29cf 1283
865c1d 1284         try:
CM 1285             config = self._makeOne()
1286             config.hook_zca()
1287             config.begin()
1288             sm = getSiteManager()
1289             self.assertEqual(sm, config.registry)
1290         finally:
1291             getSiteManager.reset()
427a02 1292
fbd01a 1293     @skip_on('py3')
427a02 1294     def test_unhook_zca(self):
865c1d 1295         from zope.component import getSiteManager
0c29cf 1296
865c1d 1297         def foo():
CM 1298             '123'
0c29cf 1299
865c1d 1300         try:
CM 1301             getSiteManager.sethook(foo)
1302             config = self._makeOne()
1303             config.unhook_zca()
1304             sm = getSiteManager()
1305             self.assertNotEqual(sm, '123')
1306         finally:
1307             getSiteManager.reset()
427a02 1308
CM 1309     def test_commit_conflict_simple(self):
1310         config = self._makeOne()
0c29cf 1311
10ddb6 1312         def view1(request):  # pragma: no cover
0c29cf 1313             pass
MM 1314
10ddb6 1315         def view2(request):  # pragma: no cover
0c29cf 1316             pass
MM 1317
427a02 1318         config.add_view(view1)
CM 1319         config.add_view(view2)
1320         self.assertRaises(ConfigurationConflictError, config.commit)
1321
1322     def test_commit_conflict_resolved_with_include(self):
1323         config = self._makeOne()
0c29cf 1324
10ddb6 1325         def view1(request):  # pragma: no cover
0c29cf 1326             pass
MM 1327
10ddb6 1328         def view2(request):  # pragma: no cover
0c29cf 1329             pass
MM 1330
427a02 1331         def includeme(config):
CM 1332             config.add_view(view2)
0c29cf 1333
427a02 1334         config.add_view(view1)
CM 1335         config.include(includeme)
1336         config.commit()
1337         registeredview = self._getViewCallable(config)
1338         self.assertEqual(registeredview.__name__, 'view1')
1339
1340     def test_commit_conflict_with_two_includes(self):
1341         config = self._makeOne()
0c29cf 1342
10ddb6 1343         def view1(request):  # pragma: no cover
0c29cf 1344             pass
MM 1345
10ddb6 1346         def view2(request):  # pragma: no cover
0c29cf 1347             pass
MM 1348
427a02 1349         def includeme1(config):
CM 1350             config.add_view(view1)
0c29cf 1351
427a02 1352         def includeme2(config):
CM 1353             config.add_view(view2)
0c29cf 1354
427a02 1355         config.include(includeme1)
CM 1356         config.include(includeme2)
af46cf 1357         try:
CM 1358             config.commit()
8e606d 1359         except ConfigurationConflictError as why:
2deac8 1360             c1, c2 = _conflictFunctions(why)
af46cf 1361             self.assertEqual(c1, 'includeme1')
CM 1362             self.assertEqual(c2, 'includeme2')
0c29cf 1363         else:  # pragma: no cover
af46cf 1364             raise AssertionError
427a02 1365
CM 1366     def test_commit_conflict_resolved_with_two_includes_and_local(self):
1367         config = self._makeOne()
0c29cf 1368
10ddb6 1369         def view1(request):  # pragma: no cover
0c29cf 1370             pass
MM 1371
10ddb6 1372         def view2(request):  # pragma: no cover
0c29cf 1373             pass
MM 1374
10ddb6 1375         def view3(request):  # pragma: no cover
0c29cf 1376             pass
MM 1377
427a02 1378         def includeme1(config):
CM 1379             config.add_view(view1)
0c29cf 1380
427a02 1381         def includeme2(config):
CM 1382             config.add_view(view2)
0c29cf 1383
427a02 1384         config.include(includeme1)
CM 1385         config.include(includeme2)
1386         config.add_view(view3)
1387         config.commit()
1388         registeredview = self._getViewCallable(config)
1389         self.assertEqual(registeredview.__name__, 'view3')
1390
1391     def test_autocommit_no_conflicts(self):
aa2fe1 1392         from pyramid.renderers import null_renderer
0c29cf 1393
427a02 1394         config = self._makeOne(autocommit=True)
0c29cf 1395
10ddb6 1396         def view1(request):  # pragma: no cover
0c29cf 1397             pass
MM 1398
10ddb6 1399         def view2(request):  # pragma: no cover
0c29cf 1400             pass
MM 1401
10ddb6 1402         def view3(request):  # pragma: no cover
0c29cf 1403             pass
MM 1404
aa2fe1 1405         config.add_view(view1, renderer=null_renderer)
CM 1406         config.add_view(view2, renderer=null_renderer)
1407         config.add_view(view3, renderer=null_renderer)
427a02 1408         config.commit()
CM 1409         registeredview = self._getViewCallable(config)
1410         self.assertEqual(registeredview.__name__, 'view3')
1411
af46cf 1412     def test_conflict_set_notfound_view(self):
CM 1413         config = self._makeOne()
0c29cf 1414
10ddb6 1415         def view1(request):  # pragma: no cover
0c29cf 1416             pass
MM 1417
10ddb6 1418         def view2(request):  # pragma: no cover
0c29cf 1419             pass
MM 1420
af46cf 1421         config.set_notfound_view(view1)
CM 1422         config.set_notfound_view(view2)
1423         try:
1424             config.commit()
8e606d 1425         except ConfigurationConflictError as why:
2deac8 1426             c1, c2 = _conflictFunctions(why)
af46cf 1427             self.assertEqual(c1, 'test_conflict_set_notfound_view')
CM 1428             self.assertEqual(c2, 'test_conflict_set_notfound_view')
0c29cf 1429         else:  # pragma: no cover
af46cf 1430             raise AssertionError
CM 1431
1432     def test_conflict_set_forbidden_view(self):
1433         config = self._makeOne()
0c29cf 1434
10ddb6 1435         def view1(request):  # pragma: no cover
0c29cf 1436             pass
MM 1437
10ddb6 1438         def view2(request):  # pragma: no cover
0c29cf 1439             pass
MM 1440
af46cf 1441         config.set_forbidden_view(view1)
CM 1442         config.set_forbidden_view(view2)
1443         try:
1444             config.commit()
8e606d 1445         except ConfigurationConflictError as why:
2deac8 1446             c1, c2 = _conflictFunctions(why)
af46cf 1447             self.assertEqual(c1, 'test_conflict_set_forbidden_view')
CM 1448             self.assertEqual(c2, 'test_conflict_set_forbidden_view')
0c29cf 1449         else:  # pragma: no cover
af46cf 1450             raise AssertionError
CM 1451
e333c2 1452     def test___getattr__missing_when_directives_exist(self):
CM 1453         config = self._makeOne()
1454         directives = {}
1455         config.registry._directives = directives
1456         self.assertRaises(AttributeError, config.__getattr__, 'wontexist')
1457
1458     def test___getattr__missing_when_directives_dont_exist(self):
1459         config = self._makeOne()
1460         self.assertRaises(AttributeError, config.__getattr__, 'wontexist')
1461
1462     def test___getattr__matches(self):
1463         config = self._makeOne()
0c29cf 1464
10ddb6 1465         def foo(config):  # pragma: no cover
0c29cf 1466             pass
MM 1467
1468         directives = {'foo': (foo, True)}
e333c2 1469         config.registry._directives = directives
CM 1470         foo_meth = config.foo
fbd01a 1471         self.assertTrue(getattr(foo_meth, im_func).__docobj__ is foo)
af46cf 1472
bb741d 1473     def test___getattr__matches_no_action_wrap(self):
CM 1474         config = self._makeOne()
0c29cf 1475
10ddb6 1476         def foo(config):  # pragma: no cover
0c29cf 1477             pass
MM 1478
1479         directives = {'foo': (foo, False)}
bb741d 1480         config.registry._directives = directives
CM 1481         foo_meth = config.foo
fbd01a 1482         self.assertTrue(getattr(foo_meth, im_func) is foo)
bb741d 1483
cad4e3 1484
0c29cf 1485 class TestConfigurator_add_directive(unittest.TestCase):
cad4e3 1486     def setUp(self):
GP 1487         from pyramid.config import Configurator
0c29cf 1488
2422ce 1489         self.config = Configurator()
cad4e3 1490
GP 1491     def test_extend_with_dotted_name(self):
dd3cc8 1492         from tests import test_config
0c29cf 1493
cad4e3 1494         config = self.config
0c29cf 1495         config.add_directive('dummy_extend', 'tests.test_config.dummy_extend')
fbd01a 1496         self.assertTrue(hasattr(config, 'dummy_extend'))
cad4e3 1497         config.dummy_extend('discrim')
b86fa9 1498         after = config.action_state
412b4a 1499         action = after.actions[-1]
CM 1500         self.assertEqual(action['discriminator'], 'discrim')
1501         self.assertEqual(action['callable'], None)
1502         self.assertEqual(action['args'], test_config)
cad4e3 1503
0d8ff5 1504     def test_add_directive_with_partial(self):
dd3cc8 1505         from tests import test_config
0c29cf 1506
0d8ff5 1507         config = self.config
WWI 1508         config.add_directive(
0c29cf 1509             'dummy_partial', 'tests.test_config.dummy_partial'
MM 1510         )
0d8ff5 1511         self.assertTrue(hasattr(config, 'dummy_partial'))
WWI 1512         config.dummy_partial()
1513         after = config.action_state
1514         action = after.actions[-1]
1515         self.assertEqual(action['discriminator'], 'partial')
1516         self.assertEqual(action['callable'], None)
1517         self.assertEqual(action['args'], test_config)
1518
1519     def test_add_directive_with_custom_callable(self):
dd3cc8 1520         from tests import test_config
0c29cf 1521
0d8ff5 1522         config = self.config
WWI 1523         config.add_directive(
0c29cf 1524             'dummy_callable', 'tests.test_config.dummy_callable'
MM 1525         )
0d8ff5 1526         self.assertTrue(hasattr(config, 'dummy_callable'))
WWI 1527         config.dummy_callable('discrim')
1528         after = config.action_state
1529         action = after.actions[-1]
1530         self.assertEqual(action['discriminator'], 'discrim')
1531         self.assertEqual(action['callable'], None)
1532         self.assertEqual(action['args'], test_config)
1533
cad4e3 1534     def test_extend_with_python_callable(self):
dd3cc8 1535         from tests import test_config
0c29cf 1536
cad4e3 1537         config = self.config
0c29cf 1538         config.add_directive('dummy_extend', dummy_extend)
fbd01a 1539         self.assertTrue(hasattr(config, 'dummy_extend'))
cad4e3 1540         config.dummy_extend('discrim')
b86fa9 1541         after = config.action_state
412b4a 1542         action = after.actions[-1]
CM 1543         self.assertEqual(action['discriminator'], 'discrim')
1544         self.assertEqual(action['callable'], None)
1545         self.assertEqual(action['args'], test_config)
cad4e3 1546
da358e 1547     def test_extend_same_name_doesnt_conflict(self):
cad4e3 1548         config = self.config
0c29cf 1549         config.add_directive('dummy_extend', dummy_extend)
MM 1550         config.add_directive('dummy_extend', dummy_extend2)
fbd01a 1551         self.assertTrue(hasattr(config, 'dummy_extend'))
da358e 1552         config.dummy_extend('discrim')
b86fa9 1553         after = config.action_state
412b4a 1554         action = after.actions[-1]
CM 1555         self.assertEqual(action['discriminator'], 'discrim')
1556         self.assertEqual(action['callable'], None)
1557         self.assertEqual(action['args'], config.registry)
cad4e3 1558
da358e 1559     def test_extend_action_method_successful(self):
2422ce 1560         config = self.config
0c29cf 1561         config.add_directive('dummy_extend', dummy_extend)
da358e 1562         config.dummy_extend('discrim')
CM 1563         config.dummy_extend('discrim')
1564         self.assertRaises(ConfigurationConflictError, config.commit)
035d03 1565
da358e 1566     def test_directive_persists_across_configurator_creations(self):
035d03 1567         config = self.config
da358e 1568         config.add_directive('dummy_extend', dummy_extend)
dd3cc8 1569         config2 = config.with_package('tests')
da358e 1570         config2.dummy_extend('discrim')
b86fa9 1571         after = config2.action_state
CM 1572         actions = after.actions
da358e 1573         self.assertEqual(len(actions), 1)
412b4a 1574         action = actions[0]
CM 1575         self.assertEqual(action['discriminator'], 'discrim')
1576         self.assertEqual(action['callable'], None)
1577         self.assertEqual(action['args'], config2.package)
2422ce 1578
0c29cf 1579
f9600f 1580 class TestConfigurator__add_predicate(unittest.TestCase):
CM 1581     def _makeOne(self):
1582         from pyramid.config import Configurator
0c29cf 1583
f9600f 1584         return Configurator()
CM 1585
1586     def test_factory_as_object(self):
1587         config = self._makeOne()
1588
0c29cf 1589         def _fakeAction(
MM 1590             discriminator,
1591             callable=None,
1592             args=(),
1593             kw=None,
1594             order=0,
1595             introspectables=(),
1596             **extra
1597         ):
f9600f 1598             self.assertEqual(len(introspectables), 1)
CM 1599             self.assertEqual(introspectables[0]['name'], 'testing')
1600             self.assertEqual(introspectables[0]['factory'], DummyPredicate)
1601
1602         config.action = _fakeAction
1603         config._add_predicate('route', 'testing', DummyPredicate)
1604
1605     def test_factory_as_dotted_name(self):
1606         config = self._makeOne()
1607
0c29cf 1608         def _fakeAction(
MM 1609             discriminator,
1610             callable=None,
1611             args=(),
1612             kw=None,
1613             order=0,
1614             introspectables=(),
1615             **extra
1616         ):
f9600f 1617             self.assertEqual(len(introspectables), 1)
CM 1618             self.assertEqual(introspectables[0]['name'], 'testing')
1619             self.assertEqual(introspectables[0]['factory'], DummyPredicate)
1620
1621         config.action = _fakeAction
1622         config._add_predicate(
0c29cf 1623             'route', 'testing', 'tests.test_config.test_init.DummyPredicate'
MM 1624         )
1625
1626
79ef3d 1627 class TestActionState(unittest.TestCase):
CM 1628     def _makeOne(self):
1629         from pyramid.config import ActionState
0c29cf 1630
79ef3d 1631         return ActionState()
0c29cf 1632
28c738 1633     def test_it(self):
79ef3d 1634         c = self._makeOne()
b86fa9 1635         self.assertEqual(c.actions, [])
79ef3d 1636
CM 1637     def test_action_simple(self):
dd3cc8 1638         from . import dummyfactory as f
0c29cf 1639
79ef3d 1640         c = self._makeOne()
CM 1641         c.actions = []
0c29cf 1642         c.action(1, f, (1,), {'x': 1})
412b4a 1643         self.assertEqual(
CM 1644             c.actions,
0c29cf 1645             [
MM 1646                 {
1647                     'args': (1,),
1648                     'callable': f,
1649                     'discriminator': 1,
1650                     'includepath': (),
1651                     'info': None,
1652                     'introspectables': (),
1653                     'kw': {'x': 1},
1654                     'order': 0,
1655                 }
1656             ],
1657         )
79ef3d 1658         c.action(None)
412b4a 1659         self.assertEqual(
CM 1660             c.actions,
0c29cf 1661             [
MM 1662                 {
1663                     'args': (1,),
1664                     'callable': f,
1665                     'discriminator': 1,
1666                     'includepath': (),
1667                     'info': None,
1668                     'introspectables': (),
1669                     'kw': {'x': 1},
1670                     'order': 0,
1671                 },
1672                 {
1673                     'args': (),
1674                     'callable': None,
1675                     'discriminator': None,
1676                     'includepath': (),
1677                     'info': None,
1678                     'introspectables': (),
1679                     'kw': {},
1680                     'order': 0,
1681                 },
1682             ],
1683         )
79ef3d 1684
b86fa9 1685     def test_action_with_includepath(self):
79ef3d 1686         c = self._makeOne()
CM 1687         c.actions = []
b86fa9 1688         c.action(None, includepath=('abc',))
412b4a 1689         self.assertEqual(
CM 1690             c.actions,
0c29cf 1691             [
MM 1692                 {
1693                     'args': (),
1694                     'callable': None,
1695                     'discriminator': None,
1696                     'includepath': ('abc',),
1697                     'info': None,
1698                     'introspectables': (),
1699                     'kw': {},
1700                     'order': 0,
1701                 }
1702             ],
1703         )
b86fa9 1704
CM 1705     def test_action_with_info(self):
1706         c = self._makeOne()
1707         c.action(None, info='abc')
412b4a 1708         self.assertEqual(
CM 1709             c.actions,
0c29cf 1710             [
MM 1711                 {
1712                     'args': (),
1713                     'callable': None,
1714                     'discriminator': None,
1715                     'includepath': (),
1716                     'info': 'abc',
1717                     'introspectables': (),
1718                     'kw': {},
1719                     'order': 0,
1720                 }
1721             ],
1722         )
b86fa9 1723
CM 1724     def test_action_with_includepath_and_info(self):
1725         c = self._makeOne()
1726         c.action(None, includepath=('spec',), info='bleh')
412b4a 1727         self.assertEqual(
CM 1728             c.actions,
0c29cf 1729             [
MM 1730                 {
1731                     'args': (),
1732                     'callable': None,
1733                     'discriminator': None,
1734                     'includepath': ('spec',),
1735                     'info': 'bleh',
1736                     'introspectables': (),
1737                     'kw': {},
1738                     'order': 0,
1739                 }
1740             ],
1741         )
79ef3d 1742
CM 1743     def test_action_with_order(self):
1744         c = self._makeOne()
1745         c.actions = []
1746         c.action(None, order=99999)
412b4a 1747         self.assertEqual(
CM 1748             c.actions,
0c29cf 1749             [
MM 1750                 {
1751                     'args': (),
1752                     'callable': None,
1753                     'discriminator': None,
1754                     'includepath': (),
1755                     'info': None,
1756                     'introspectables': (),
1757                     'kw': {},
1758                     'order': 99999,
1759                 }
1760             ],
1761         )
2e651e 1762
CM 1763     def test_action_with_introspectables(self):
1764         c = self._makeOne()
1765         c.actions = []
1766         intr = DummyIntrospectable()
1767         c.action(None, introspectables=(intr,))
1768         self.assertEqual(
1769             c.actions,
0c29cf 1770             [
MM 1771                 {
1772                     'args': (),
1773                     'callable': None,
1774                     'discriminator': None,
1775                     'includepath': (),
1776                     'info': None,
1777                     'introspectables': (intr,),
1778                     'kw': {},
1779                     'order': 0,
1780                 }
1781             ],
1782         )
79ef3d 1783
CM 1784     def test_processSpec(self):
1785         c = self._makeOne()
1786         self.assertTrue(c.processSpec('spec'))
1787         self.assertFalse(c.processSpec('spec'))
1788
2e651e 1789     def test_execute_actions_tuples(self):
79ef3d 1790         output = []
0c29cf 1791
79ef3d 1792         def f(*a, **k):
2e651e 1793             output.append((a, k))
0c29cf 1794
79ef3d 1795         c = self._makeOne()
CM 1796         c.actions = [
1797             (1, f, (1,)),
0c29cf 1798             (1, f, (11,), {}, ('x',)),
79ef3d 1799             (2, f, (2,)),
CM 1800             (None, None),
0c29cf 1801         ]
79ef3d 1802         c.execute_actions()
0c29cf 1803         self.assertEqual(output, [((1,), {}), ((2,), {})])
2e651e 1804
CM 1805     def test_execute_actions_dicts(self):
1806         output = []
0c29cf 1807
2e651e 1808         def f(*a, **k):
CM 1809             output.append((a, k))
0c29cf 1810
2e651e 1811         c = self._makeOne()
CM 1812         c.actions = [
0c29cf 1813             {
MM 1814                 'discriminator': 1,
1815                 'callable': f,
1816                 'args': (1,),
1817                 'kw': {},
1818                 'order': 0,
1819                 'includepath': (),
1820                 'info': None,
1821                 'introspectables': (),
1822             },
1823             {
1824                 'discriminator': 1,
1825                 'callable': f,
1826                 'args': (11,),
1827                 'kw': {},
1828                 'includepath': ('x',),
1829                 'order': 0,
1830                 'info': None,
1831                 'introspectables': (),
1832             },
1833             {
1834                 'discriminator': 2,
1835                 'callable': f,
1836                 'args': (2,),
1837                 'kw': {},
1838                 'order': 0,
1839                 'includepath': (),
1840                 'info': None,
1841                 'introspectables': (),
1842             },
1843             {
1844                 'discriminator': None,
1845                 'callable': None,
1846                 'args': (),
1847                 'kw': {},
1848                 'order': 0,
1849                 'includepath': (),
1850                 'info': None,
1851                 'introspectables': (),
1852             },
1853         ]
2e651e 1854         c.execute_actions()
0c29cf 1855         self.assertEqual(output, [((1,), {}), ((2,), {})])
2e651e 1856
CM 1857     def test_execute_actions_with_introspectables(self):
1858         output = []
0c29cf 1859
2e651e 1860         def f(*a, **k):
CM 1861             output.append((a, k))
0c29cf 1862
2e651e 1863         c = self._makeOne()
CM 1864         intr = DummyIntrospectable()
1865         c.actions = [
0c29cf 1866             {
MM 1867                 'discriminator': 1,
1868                 'callable': f,
1869                 'args': (1,),
1870                 'kw': {},
1871                 'order': 0,
1872                 'includepath': (),
1873                 'info': None,
1874                 'introspectables': (intr,),
1875             }
1876         ]
844ed9 1877         introspector = object()
2e651e 1878         c.execute_actions(introspector=introspector)
0c29cf 1879         self.assertEqual(output, [((1,), {})])
2e651e 1880         self.assertEqual(intr.registered, [(introspector, None)])
CM 1881
1882     def test_execute_actions_with_introspectable_no_callable(self):
1883         c = self._makeOne()
1884         intr = DummyIntrospectable()
1885         c.actions = [
0c29cf 1886             {
MM 1887                 'discriminator': 1,
1888                 'callable': None,
1889                 'args': (1,),
1890                 'kw': {},
1891                 'order': 0,
1892                 'includepath': (),
1893                 'info': None,
1894                 'introspectables': (intr,),
1895             }
1896         ]
844ed9 1897         introspector = object()
2e651e 1898         c.execute_actions(introspector=introspector)
CM 1899         self.assertEqual(intr.registered, [(introspector, None)])
79ef3d 1900
CM 1901     def test_execute_actions_error(self):
1902         output = []
0c29cf 1903
79ef3d 1904         def f(*a, **k):
CM 1905             output.append(('f', a, k))
0c29cf 1906
79ef3d 1907         def bad():
CM 1908             raise NotImplementedError
0c29cf 1909
79ef3d 1910         c = self._makeOne()
CM 1911         c.actions = [
1912             (1, f, (1,)),
0c29cf 1913             (1, f, (11,), {}, ('x',)),
79ef3d 1914             (2, f, (2,)),
0c29cf 1915             (3, bad, (), {}, (), 'oops'),
MM 1916         ]
79ef3d 1917         self.assertRaises(ConfigurationExecutionError, c.execute_actions)
CM 1918         self.assertEqual(output, [('f', (1,), {}), ('f', (2,), {})])
1919
873fa0 1920     def test_reentrant_action(self):
MM 1921         output = []
1922         c = self._makeOne()
0c29cf 1923
873fa0 1924         def f(*a, **k):
MM 1925             output.append(('f', a, k))
1926             c.actions.append((3, g, (8,), {}))
0c29cf 1927
873fa0 1928         def g(*a, **k):
MM 1929             output.append(('g', a, k))
0c29cf 1930
MM 1931         c.actions = [(1, f, (1,))]
873fa0 1932         c.execute_actions()
MM 1933         self.assertEqual(output, [('f', (1,), {}), ('g', (8,), {})])
1934
2cb7e0 1935     def test_reentrant_action_with_deferred_discriminator(self):
MM 1936         # see https://github.com/Pylons/pyramid/issues/2697
1937         from pyramid.registry import Deferred
0c29cf 1938
2cb7e0 1939         output = []
MM 1940         c = self._makeOne()
0c29cf 1941
2cb7e0 1942         def f(*a, **k):
MM 1943             output.append(('f', a, k))
1944             c.actions.append((4, g, (4,), {}, (), None, 2))
0c29cf 1945
2cb7e0 1946         def g(*a, **k):
MM 1947             output.append(('g', a, k))
0c29cf 1948
2cb7e0 1949         def h(*a, **k):
MM 1950             output.append(('h', a, k))
0c29cf 1951
2cb7e0 1952         def discrim():
MM 1953             self.assertEqual(output, [('f', (1,), {}), ('g', (2,), {})])
1954             return 3
0c29cf 1955
2cb7e0 1956         d = Deferred(discrim)
MM 1957         c.actions = [
0c29cf 1958             (d, h, (3,), {}, (), None, 1),  # order 1
MM 1959             (1, f, (1,)),  # order 0
1960             (2, g, (2,)),  # order 0
2cb7e0 1961         ]
MM 1962         c.execute_actions()
0c29cf 1963         self.assertEqual(
MM 1964             output,
1965             [
1966                 ('f', (1,), {}),
1967                 ('g', (2,), {}),
1968                 ('h', (3,), {}),
1969                 ('g', (4,), {}),
1970             ],
1971         )
2cb7e0 1972
873fa0 1973     def test_reentrant_action_error(self):
MM 1974         from pyramid.exceptions import ConfigurationError
0c29cf 1975
873fa0 1976         c = self._makeOne()
0c29cf 1977
873fa0 1978         def f(*a, **k):
MM 1979             c.actions.append((3, g, (8,), {}, (), None, -1))
0c29cf 1980
10ddb6 1981         def g(*a, **k):  # pragma: no cover
0c29cf 1982             pass
MM 1983
1984         c.actions = [(1, f, (1,))]
873fa0 1985         self.assertRaises(ConfigurationError, c.execute_actions)
MM 1986
1987     def test_reentrant_action_without_clear(self):
1988         c = self._makeOne()
0c29cf 1989
873fa0 1990         def f(*a, **k):
MM 1991             c.actions.append((3, g, (8,)))
0c29cf 1992
MM 1993         def g(*a, **k):
1994             pass
1995
1996         c.actions = [(1, f, (1,))]
873fa0 1997         c.execute_actions(clear=False)
0c29cf 1998         self.assertEqual(c.actions, [(1, f, (1,)), (3, g, (8,))])
873fa0 1999
08ff26 2000     def test_executing_conflicting_action_across_orders(self):
MM 2001         from pyramid.exceptions import ConfigurationConflictError
0c29cf 2002
08ff26 2003         c = self._makeOne()
0c29cf 2004
MM 2005         def f(*a, **k):
2006             pass
2007
10ddb6 2008         def g(*a, **k):  # pragma: no cover
0c29cf 2009             pass
MM 2010
2011         c.actions = [(1, f, (1,), {}, (), None, -1), (1, g, (2,))]
08ff26 2012         self.assertRaises(ConfigurationConflictError, c.execute_actions)
MM 2013
2014     def test_executing_conflicting_action_across_reentrant_orders(self):
2015         from pyramid.exceptions import ConfigurationConflictError
0c29cf 2016
08ff26 2017         c = self._makeOne()
0c29cf 2018
08ff26 2019         def f(*a, **k):
MM 2020             c.actions.append((1, g, (8,)))
0c29cf 2021
10ddb6 2022         def g(*a, **k):  # pragma: no cover
0c29cf 2023             pass
MM 2024
2025         c.actions = [(1, f, (1,), {}, (), None, -1)]
08ff26 2026         self.assertRaises(ConfigurationConflictError, c.execute_actions)
0c29cf 2027
08ff26 2028
a8fab3 2029 class Test_reentrant_action_functional(unittest.TestCase):
CM 2030     def _makeConfigurator(self, *arg, **kw):
2031         from pyramid.config import Configurator
0c29cf 2032
a8fab3 2033         config = Configurator(*arg, **kw)
CM 2034         return config
2035
2036     def test_functional(self):
2037         def add_auto_route(config, name, view):
0c29cf 2038             def register():
MM 2039                 config.add_view(route_name=name, view=view)
2040                 config.add_route(name, '/' + name)
2041
2042             config.action(('auto route', name), register, order=-30)
2043
a8fab3 2044         config = self._makeConfigurator()
CM 2045         config.add_directive('add_auto_route', add_auto_route)
0c29cf 2046
10ddb6 2047         def my_view(request):  # pragma: no cover
0c29cf 2048             return request.response
MM 2049
a8fab3 2050         config.add_auto_route('foo', my_view)
CM 2051         config.commit()
2052         from pyramid.interfaces import IRoutesMapper
0c29cf 2053
a8fab3 2054         mapper = config.registry.getUtility(IRoutesMapper)
CM 2055         routes = mapper.get_routes()
2056         route = routes[0]
2057         self.assertEqual(len(routes), 1)
2058         self.assertEqual(route.name, 'foo')
2059         self.assertEqual(route.path, '/foo')
2060
2cb7e0 2061     def test_deferred_discriminator(self):
MM 2062         # see https://github.com/Pylons/pyramid/issues/2697
2063         from pyramid.config import PHASE0_CONFIG
0c29cf 2064
2cb7e0 2065         config = self._makeConfigurator()
0c29cf 2066
MM 2067         def deriver(view, info):
2068             return view
2069
2cb7e0 2070         deriver.options = ('foo',)
MM 2071         config.add_view_deriver(deriver, 'foo_view')
2072         # add_view uses a deferred discriminator and will fail if executed
2073         # prior to add_view_deriver executing its action
2074         config.add_view(lambda r: r.response, name='', foo=1)
0c29cf 2075
2cb7e0 2076         def dummy_action():
MM 2077             # trigger a re-entrant action
2078             config.action(None, lambda: None)
0c29cf 2079
2cb7e0 2080         config.action(None, dummy_action, order=PHASE0_CONFIG)
MM 2081         config.commit()
0c29cf 2082
a8fab3 2083
79ef3d 2084 class Test_resolveConflicts(unittest.TestCase):
CM 2085     def _callFUT(self, actions):
2086         from pyramid.config import resolveConflicts
0c29cf 2087
79ef3d 2088         return resolveConflicts(actions)
CM 2089
2e651e 2090     def test_it_success_tuples(self):
dd3cc8 2091         from . import dummyfactory as f
0c29cf 2092
MM 2093         result = self._callFUT(
2094             [
2095                 (None, f),
2096                 (1, f, (1,), {}, (), 'first'),
2097                 (1, f, (2,), {}, ('x',), 'second'),
2098                 (1, f, (3,), {}, ('y',), 'third'),
2099                 (4, f, (4,), {}, ('y',), 'should be last', 99999),
2100                 (3, f, (3,), {}, ('y',)),
2101                 (None, f, (5,), {}, ('y',)),
2102             ]
2103         )
9c8ec5 2104         result = list(result)
412b4a 2105         self.assertEqual(
CM 2106             result,
0c29cf 2107             [
MM 2108                 {
2109                     'info': None,
2110                     'args': (),
2111                     'callable': f,
2112                     'introspectables': (),
2113                     'kw': {},
2114                     'discriminator': None,
2115                     'includepath': (),
2116                     'order': 0,
2117                 },
2118                 {
2119                     'info': 'first',
2120                     'args': (1,),
2121                     'callable': f,
2122                     'introspectables': (),
2123                     'kw': {},
2124                     'discriminator': 1,
2125                     'includepath': (),
2126                     'order': 0,
2127                 },
2128                 {
2129                     'info': None,
2130                     'args': (3,),
2131                     'callable': f,
2132                     'introspectables': (),
2133                     'kw': {},
2134                     'discriminator': 3,
2135                     'includepath': ('y',),
2136                     'order': 0,
2137                 },
2138                 {
2139                     'info': None,
2140                     'args': (5,),
2141                     'callable': f,
2142                     'introspectables': (),
2143                     'kw': {},
2144                     'discriminator': None,
2145                     'includepath': ('y',),
2146                     'order': 0,
2147                 },
2148                 {
2149                     'info': 'should be last',
2150                     'args': (4,),
2151                     'callable': f,
2152                     'introspectables': (),
2153                     'kw': {},
2154                     'discriminator': 4,
2155                     'includepath': ('y',),
2156                     'order': 99999,
2157                 },
2158             ],
2159         )
2e651e 2160
CM 2161     def test_it_success_dicts(self):
dd3cc8 2162         from . import dummyfactory as f
0c29cf 2163
MM 2164         result = self._callFUT(
2165             [
2166                 (None, f),
2167                 (1, f, (1,), {}, (), 'first'),
2168                 (1, f, (2,), {}, ('x',), 'second'),
2169                 (1, f, (3,), {}, ('y',), 'third'),
2170                 (4, f, (4,), {}, ('y',), 'should be last', 99999),
2171                 (3, f, (3,), {}, ('y',)),
2172                 (None, f, (5,), {}, ('y',)),
2173             ]
2174         )
9c8ec5 2175         result = list(result)
2e651e 2176         self.assertEqual(
CM 2177             result,
0c29cf 2178             [
MM 2179                 {
2180                     'info': None,
2181                     'args': (),
2182                     'callable': f,
2183                     'introspectables': (),
2184                     'kw': {},
2185                     'discriminator': None,
2186                     'includepath': (),
2187                     'order': 0,
2188                 },
2189                 {
2190                     'info': 'first',
2191                     'args': (1,),
2192                     'callable': f,
2193                     'introspectables': (),
2194                     'kw': {},
2195                     'discriminator': 1,
2196                     'includepath': (),
2197                     'order': 0,
2198                 },
2199                 {
2200                     'info': None,
2201                     'args': (3,),
2202                     'callable': f,
2203                     'introspectables': (),
2204                     'kw': {},
2205                     'discriminator': 3,
2206                     'includepath': ('y',),
2207                     'order': 0,
2208                 },
2209                 {
2210                     'info': None,
2211                     'args': (5,),
2212                     'callable': f,
2213                     'introspectables': (),
2214                     'kw': {},
2215                     'discriminator': None,
2216                     'includepath': ('y',),
2217                     'order': 0,
2218                 },
2219                 {
2220                     'info': 'should be last',
2221                     'args': (4,),
2222                     'callable': f,
2223                     'introspectables': (),
2224                     'kw': {},
2225                     'discriminator': 4,
2226                     'includepath': ('y',),
2227                     'order': 99999,
2228                 },
2229             ],
2230         )
79ef3d 2231
CM 2232     def test_it_conflict(self):
dd3cc8 2233         from . import dummyfactory as f
0c29cf 2234
MM 2235         result = self._callFUT(
2236             [
2237                 (None, f),
2238                 (1, f, (2,), {}, ('x',), 'eek'),  # will conflict
2239                 (1, f, (3,), {}, ('y',), 'ack'),  # will conflict
2240                 (4, f, (4,), {}, ('y',)),
2241                 (3, f, (3,), {}, ('y',)),
2242                 (None, f, (5,), {}, ('y',)),
2243             ]
2244         )
9c8ec5 2245         self.assertRaises(ConfigurationConflictError, list, result)
427a02 2246
82f677 2247     def test_it_with_actions_grouped_by_order(self):
dd3cc8 2248         from . import dummyfactory as f
0c29cf 2249
MM 2250         result = self._callFUT(
2251             [
2252                 (None, f),  # X
2253                 (1, f, (1,), {}, (), 'third', 10),  # X
2254                 (1, f, (2,), {}, ('x',), 'fourth', 10),
2255                 (1, f, (3,), {}, ('y',), 'fifth', 10),
2256                 (2, f, (1,), {}, (), 'sixth', 10),  # X
2257                 (3, f, (1,), {}, (), 'seventh', 10),  # X
2258                 (5, f, (4,), {}, ('y',), 'eighth', 99999),  # X
2259                 (4, f, (3,), {}, (), 'first', 5),  # X
2260                 (4, f, (5,), {}, ('y',), 'second', 5),
2261             ]
2262         )
9c8ec5 2263         result = list(result)
82f677 2264         self.assertEqual(len(result), 6)
CM 2265         # resolved actions should be grouped by (order, i)
2266         self.assertEqual(
2267             result,
0c29cf 2268             [
MM 2269                 {
2270                     'info': None,
2271                     'args': (),
2272                     'callable': f,
2273                     'introspectables': (),
2274                     'kw': {},
2275                     'discriminator': None,
2276                     'includepath': (),
2277                     'order': 0,
2278                 },
2279                 {
2280                     'info': 'first',
2281                     'args': (3,),
2282                     'callable': f,
2283                     'introspectables': (),
2284                     'kw': {},
2285                     'discriminator': 4,
2286                     'includepath': (),
2287                     'order': 5,
2288                 },
2289                 {
2290                     'info': 'third',
2291                     'args': (1,),
2292                     'callable': f,
2293                     'introspectables': (),
2294                     'kw': {},
2295                     'discriminator': 1,
2296                     'includepath': (),
2297                     'order': 10,
2298                 },
2299                 {
2300                     'info': 'sixth',
2301                     'args': (1,),
2302                     'callable': f,
2303                     'introspectables': (),
2304                     'kw': {},
2305                     'discriminator': 2,
2306                     'includepath': (),
2307                     'order': 10,
2308                 },
2309                 {
2310                     'info': 'seventh',
2311                     'args': (1,),
2312                     'callable': f,
2313                     'introspectables': (),
2314                     'kw': {},
2315                     'discriminator': 3,
2316                     'includepath': (),
2317                     'order': 10,
2318                 },
2319                 {
2320                     'info': 'eighth',
2321                     'args': (4,),
2322                     'callable': f,
2323                     'introspectables': (),
2324                     'kw': {},
2325                     'discriminator': 5,
2326                     'includepath': ('y',),
2327                     'order': 99999,
2328                 },
2329             ],
2330         )
08ff26 2331
MM 2332     def test_override_success_across_orders(self):
dd3cc8 2333         from . import dummyfactory as f
0c29cf 2334
MM 2335         result = self._callFUT(
2336             [
2337                 (1, f, (2,), {}, ('x',), 'eek', 0),
2338                 (1, f, (3,), {}, ('x', 'y'), 'ack', 10),
2339             ]
2340         )
08ff26 2341         result = list(result)
0c29cf 2342         self.assertEqual(
MM 2343             result,
2344             [
2345                 {
2346                     'info': 'eek',
2347                     'args': (2,),
2348                     'callable': f,
2349                     'introspectables': (),
2350                     'kw': {},
2351                     'discriminator': 1,
2352                     'includepath': ('x',),
2353                     'order': 0,
2354                 }
2355             ],
2356         )
08ff26 2357
MM 2358     def test_conflicts_across_orders(self):
dd3cc8 2359         from . import dummyfactory as f
0c29cf 2360
MM 2361         result = self._callFUT(
2362             [
2363                 (1, f, (2,), {}, ('x', 'y'), 'eek', 0),
2364                 (1, f, (3,), {}, ('x'), 'ack', 10),
2365             ]
2366         )
08ff26 2367         self.assertRaises(ConfigurationConflictError, list, result)
0c29cf 2368
82f677 2369
3d43f7 2370 class TestGlobalRegistriesIntegration(unittest.TestCase):
CM 2371     def setUp(self):
2372         from pyramid.config import global_registries
0c29cf 2373
3d43f7 2374         global_registries.empty()
CM 2375
2376     tearDown = setUp
2377
2378     def _makeConfigurator(self, *arg, **kw):
2379         from pyramid.config import Configurator
0c29cf 2380
3d43f7 2381         config = Configurator(*arg, **kw)
CM 2382         return config
2383
2384     def test_global_registries_empty(self):
2385         from pyramid.config import global_registries
0c29cf 2386
3d43f7 2387         self.assertEqual(global_registries.last, None)
CM 2388
2389     def test_global_registries(self):
2390         from pyramid.config import global_registries
0c29cf 2391
3d43f7 2392         config1 = self._makeConfigurator()
CM 2393         config1.make_wsgi_app()
2394         self.assertEqual(global_registries.last, config1.registry)
2395         config2 = self._makeConfigurator()
2396         config2.make_wsgi_app()
2397         self.assertEqual(global_registries.last, config2.registry)
0c29cf 2398         self.assertEqual(
MM 2399             list(global_registries), [config1.registry, config2.registry]
2400         )
3d43f7 2401         global_registries.remove(config2.registry)
CM 2402         self.assertEqual(global_registries.last, config1.registry)
0c29cf 2403
3d43f7 2404
427a02 2405 class DummyRequest:
CM 2406     subpath = ()
2407     matchdict = None
849196 2408     request_iface = IRequest
0c29cf 2409
f426e5 2410     def __init__(self, environ=None):
CM 2411         if environ is None:
2412             environ = {}
2413         self.environ = environ
427a02 2414         self.params = {}
CM 2415         self.cookies = {}
2416
0c29cf 2417
427a02 2418 class DummyThreadLocalManager(object):
804eb0 2419     def __init__(self):
MM 2420         self.pushed = {'registry': None, 'request': None}
2421         self.popped = False
0c29cf 2422
427a02 2423     def push(self, d):
CM 2424         self.pushed = d
0c29cf 2425
804eb0 2426     def get(self):
MM 2427         return self.pushed
0c29cf 2428
427a02 2429     def pop(self):
CM 2430         self.popped = True
2431
0c29cf 2432
3b7334 2433 @implementer(IDummy)
427a02 2434 class DummyEvent:
3b7334 2435     pass
0c29cf 2436
25025a 2437
d868ff 2438 class DummyRegistry(object):
a00621 2439     def __init__(self, adaptation=None, util=None):
d868ff 2440         self.utilities = []
CM 2441         self.adapters = []
2442         self.adaptation = adaptation
a00621 2443         self.util = util
0c29cf 2444
d868ff 2445     def subscribers(self, events, name):
CM 2446         self.events = events
2447         return events
0c29cf 2448
d868ff 2449     def registerUtility(self, *arg, **kw):
CM 2450         self.utilities.append((arg, kw))
0c29cf 2451
d868ff 2452     def registerAdapter(self, *arg, **kw):
CM 2453         self.adapters.append((arg, kw))
0c29cf 2454
d868ff 2455     def queryAdapter(self, *arg, **kw):
CM 2456         return self.adaptation
0c29cf 2457
a00621 2458     def queryUtility(self, *arg, **kw):
CM 2459         return self.util
0c29cf 2460
MM 2461
4d65ea 2462 class IOther(Interface):
CM 2463     pass
0c29cf 2464
4d65ea 2465
2deac8 2466 def _conflictFunctions(e):
CM 2467     conflicts = e._conflicts.values()
2468     for conflict in conflicts:
2469         for confinst in conflict:
549cf7 2470             yield confinst.function
2deac8 2471
0c29cf 2472
940ab0 2473 class DummyActionState(object):
CM 2474     autocommit = False
2475     info = ''
0c29cf 2476
940ab0 2477     def __init__(self):
CM 2478         self.actions = []
0c29cf 2479
940ab0 2480     def action(self, *arg, **kw):
CM 2481         self.actions.append((arg, kw))
0c29cf 2482
2e651e 2483
CM 2484 class DummyIntrospectable(object):
2485     def __init__(self):
2486         self.registered = []
0c29cf 2487
2e651e 2488     def register(self, introspector, action_info):
CM 2489         self.registered.append((introspector, action_info))
0c29cf 2490
MM 2491
f9600f 2492 class DummyPredicate(object):
CM 2493     pass