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