Michael Merickel
2018-10-18 e4c0570d5c67ddf0ad9502169b59475ba0784d82
commit | author | age
5bf23f 1 import os
10ddb6 2 import unittest
5bf23f 3
fbd01a 4 from pyramid.compat import im_func
CM 5 from pyramid.testing import skip_on
3b7334 6
dd3cc8 7 from . import dummy_tween_factory
MM 8 from . import dummy_include
9 from . import dummy_extend
10 from . import dummy_extend2
11 from . import DummyContext
5bf23f 12
79ef3d 13 from pyramid.exceptions import ConfigurationExecutionError
CM 14 from pyramid.exceptions import ConfigurationConflictError
849196 15
CM 16 from pyramid.interfaces import IRequest
79ef3d 17
0c29cf 18
427a02 19 class ConfiguratorTests(unittest.TestCase):
CM 20     def _makeOne(self, *arg, **kw):
21         from pyramid.config import Configurator
0c29cf 22
58bc25 23         config = Configurator(*arg, **kw)
CM 24         return config
427a02 25
0c29cf 26     def _getViewCallable(
MM 27         self,
28         config,
29         ctx_iface=None,
30         request_iface=None,
31         name='',
32         exception_view=False,
33     ):
427a02 34         from zope.interface import Interface
CM 35         from pyramid.interfaces import IView
36         from pyramid.interfaces import IViewClassifier
37         from pyramid.interfaces import IExceptionViewClassifier
0c29cf 38
MM 39         if exception_view:  # pragma: no cover
427a02 40             classifier = IExceptionViewClassifier
CM 41         else:
42             classifier = IViewClassifier
43         if ctx_iface is None:
44             ctx_iface = Interface
45         if request_iface is None:
46             request_iface = IRequest
47         return config.registry.adapters.lookup(
0c29cf 48             (classifier, request_iface, ctx_iface),
MM 49             IView,
50             name=name,
51             default=None,
52         )
427a02 53
CM 54     def _registerEventListener(self, config, event_iface=None):
0c29cf 55         if event_iface is None:  # pragma: no cover
427a02 56             from zope.interface import Interface
0c29cf 57
427a02 58             event_iface = Interface
CM 59         L = []
0c29cf 60
427a02 61         def subscriber(*event):
CM 62             L.extend(event)
0c29cf 63
427a02 64         config.registry.registerHandler(subscriber, (event_iface,))
CM 65         return L
66
67     def _makeRequest(self, config):
68         request = DummyRequest()
69         request.registry = config.registry
70         return request
ed7ffe 71
427a02 72     def test_ctor_no_registry(self):
CM 73         import sys
74         from pyramid.interfaces import ISettings
75         from pyramid.config import Configurator
76         from pyramid.interfaces import IRendererFactory
0c29cf 77
427a02 78         config = Configurator()
dd3cc8 79         this_pkg = sys.modules['tests.test_config']
a1d395 80         self.assertTrue(config.registry.getUtility(ISettings))
427a02 81         self.assertEqual(config.package, this_pkg)
381de3 82         config.commit()
a1d395 83         self.assertTrue(config.registry.getUtility(IRendererFactory, 'json'))
CM 84         self.assertTrue(config.registry.getUtility(IRendererFactory, 'string'))
427a02 85
CM 86     def test_begin(self):
87         from pyramid.config import Configurator
0c29cf 88
427a02 89         config = Configurator()
CM 90         manager = DummyThreadLocalManager()
91         config.manager = manager
92         config.begin()
0c29cf 93         self.assertEqual(
MM 94             manager.pushed, {'registry': config.registry, 'request': None}
95         )
427a02 96         self.assertEqual(manager.popped, False)
CM 97
98     def test_begin_with_request(self):
99         from pyramid.config import Configurator
0c29cf 100
427a02 101         config = Configurator()
CM 102         request = object()
103         manager = DummyThreadLocalManager()
104         config.manager = manager
105         config.begin(request=request)
0c29cf 106         self.assertEqual(
MM 107             manager.pushed, {'registry': config.registry, 'request': request}
108         )
427a02 109         self.assertEqual(manager.popped, False)
CM 110
804eb0 111     def test_begin_overrides_request(self):
MM 112         from pyramid.config import Configurator
0c29cf 113
804eb0 114         config = Configurator()
MM 115         manager = DummyThreadLocalManager()
116         req = object()
117         # set it up for auto-propagation
118         pushed = {'registry': config.registry, 'request': None}
119         manager.pushed = pushed
120         config.manager = manager
121         config.begin(req)
122         self.assertTrue(manager.pushed is not pushed)
123         self.assertEqual(manager.pushed['request'], req)
124         self.assertEqual(manager.pushed['registry'], config.registry)
125
126     def test_begin_propagates_request_for_same_registry(self):
127         from pyramid.config import Configurator
0c29cf 128
804eb0 129         config = Configurator()
MM 130         manager = DummyThreadLocalManager()
131         req = object()
132         pushed = {'registry': config.registry, 'request': req}
133         manager.pushed = pushed
134         config.manager = manager
135         config.begin()
136         self.assertTrue(manager.pushed is not pushed)
137         self.assertEqual(manager.pushed['request'], req)
138         self.assertEqual(manager.pushed['registry'], config.registry)
139
140     def test_begin_does_not_propagate_request_for_diff_registry(self):
141         from pyramid.config import Configurator
0c29cf 142
804eb0 143         config = Configurator()
MM 144         manager = DummyThreadLocalManager()
145         req = object()
146         pushed = {'registry': object(), 'request': req}
147         manager.pushed = pushed
148         config.manager = manager
149         config.begin()
150         self.assertTrue(manager.pushed is not pushed)
151         self.assertEqual(manager.pushed['request'], None)
152         self.assertEqual(manager.pushed['registry'], config.registry)
153
427a02 154     def test_end(self):
CM 155         from pyramid.config import Configurator
0c29cf 156
427a02 157         config = Configurator()
CM 158         manager = DummyThreadLocalManager()
804eb0 159         pushed = manager.pushed
427a02 160         config.manager = manager
CM 161         config.end()
804eb0 162         self.assertEqual(manager.pushed, pushed)
427a02 163         self.assertEqual(manager.popped, True)
CM 164
134ef7 165     def test_context_manager(self):
MM 166         from pyramid.config import Configurator
0c29cf 167
134ef7 168         config = Configurator()
MM 169         manager = DummyThreadLocalManager()
170         config.manager = manager
171         view = lambda r: None
172         with config as ctx:
173             self.assertTrue(config is ctx)
0c29cf 174             self.assertEqual(
MM 175                 manager.pushed, {'registry': config.registry, 'request': None}
176             )
134ef7 177             self.assertFalse(manager.popped)
MM 178             config.add_view(view)
179         self.assertTrue(manager.popped)
180         config.add_view(view)  # did not raise a conflict because of commit
181         config.commit()
182
427a02 183     def test_ctor_with_package_registry(self):
CM 184         import sys
185         from pyramid.config import Configurator
0c29cf 186
427a02 187         pkg = sys.modules['pyramid']
CM 188         config = Configurator(package=pkg)
189         self.assertEqual(config.package, pkg)
190
191     def test_ctor_noreg_custom_settings(self):
192         from pyramid.interfaces import ISettings
0c29cf 193
MM 194         settings = {'reload_templates': True, 'mysetting': True}
427a02 195         config = self._makeOne(settings=settings)
CM 196         settings = config.registry.getUtility(ISettings)
197         self.assertEqual(settings['reload_templates'], True)
198         self.assertEqual(settings['debug_authorization'], False)
199         self.assertEqual(settings['mysetting'], True)
200
201     def test_ctor_noreg_debug_logger_None_default(self):
202         from pyramid.interfaces import IDebugLogger
0c29cf 203
427a02 204         config = self._makeOne()
CM 205         logger = config.registry.getUtility(IDebugLogger)
dd3cc8 206         self.assertEqual(logger.name, 'tests.test_config')
427a02 207
CM 208     def test_ctor_noreg_debug_logger_non_None(self):
209         from pyramid.interfaces import IDebugLogger
0c29cf 210
427a02 211         logger = object()
CM 212         config = self._makeOne(debug_logger=logger)
213         result = config.registry.getUtility(IDebugLogger)
214         self.assertEqual(logger, result)
215
216     def test_ctor_authentication_policy(self):
217         from pyramid.interfaces import IAuthenticationPolicy
0c29cf 218
427a02 219         policy = object()
CM 220         config = self._makeOne(authentication_policy=policy)
381de3 221         config.commit()
427a02 222         result = config.registry.getUtility(IAuthenticationPolicy)
CM 223         self.assertEqual(policy, result)
224
225     def test_ctor_authorization_policy_only(self):
226         policy = object()
ea824f 227         config = self._makeOne(authorization_policy=policy)
CM 228         self.assertRaises(ConfigurationExecutionError, config.commit)
427a02 229
CM 230     def test_ctor_no_root_factory(self):
231         from pyramid.interfaces import IRootFactory
0c29cf 232
427a02 233         config = self._makeOne()
ea824f 234         self.assertEqual(config.registry.queryUtility(IRootFactory), None)
CM 235         config.commit()
2a818a 236         self.assertEqual(config.registry.queryUtility(IRootFactory), None)
CM 237
238     def test_ctor_with_root_factory(self):
239         from pyramid.interfaces import IRootFactory
0c29cf 240
2a818a 241         factory = object()
CM 242         config = self._makeOne(root_factory=factory)
243         self.assertEqual(config.registry.queryUtility(IRootFactory), None)
244         config.commit()
245         self.assertEqual(config.registry.queryUtility(IRootFactory), factory)
427a02 246
CM 247     def test_ctor_alternate_renderers(self):
248         from pyramid.interfaces import IRendererFactory
0c29cf 249
427a02 250         renderer = object()
CM 251         config = self._makeOne(renderers=[('yeah', renderer)])
381de3 252         config.commit()
0c29cf 253         self.assertEqual(
MM 254             config.registry.getUtility(IRendererFactory, 'yeah'), renderer
255         )
427a02 256
b93af9 257     def test_ctor_default_renderers(self):
CM 258         from pyramid.interfaces import IRendererFactory
259         from pyramid.renderers import json_renderer_factory
0c29cf 260
b93af9 261         config = self._makeOne()
0c29cf 262         self.assertEqual(
MM 263             config.registry.getUtility(IRendererFactory, 'json'),
264             json_renderer_factory,
265         )
b93af9 266
427a02 267     def test_ctor_default_permission(self):
CM 268         from pyramid.interfaces import IDefaultPermission
0c29cf 269
427a02 270         config = self._makeOne(default_permission='view')
f67ba4 271         config.commit()
0c29cf 272         self.assertEqual(
MM 273             config.registry.getUtility(IDefaultPermission), 'view'
274         )
427a02 275
CM 276     def test_ctor_session_factory(self):
277         from pyramid.interfaces import ISessionFactory
0c29cf 278
637bda 279         factory = object()
CM 280         config = self._makeOne(session_factory=factory)
ea824f 281         self.assertEqual(config.registry.queryUtility(ISessionFactory), None)
CM 282         config.commit()
637bda 283         self.assertEqual(config.registry.getUtility(ISessionFactory), factory)
80aa77 284
CM 285     def test_ctor_default_view_mapper(self):
286         from pyramid.interfaces import IViewMapperFactory
0c29cf 287
80aa77 288         mapper = object()
CM 289         config = self._makeOne(default_view_mapper=mapper)
381de3 290         config.commit()
0c29cf 291         self.assertEqual(
MM 292             config.registry.getUtility(IViewMapperFactory), mapper
293         )
427a02 294
1ffb8e 295     def test_ctor_httpexception_view_default(self):
8c2a9e 296         from pyramid.interfaces import IExceptionResponse
99edc5 297         from pyramid.httpexceptions import default_exceptionresponse_view
0c29cf 298
1ffb8e 299         config = self._makeOne()
0c29cf 300         view = self._getViewCallable(
MM 301             config, ctx_iface=IExceptionResponse, request_iface=IRequest
302         )
58bc25 303         self.assertTrue(view.__wraps__ is default_exceptionresponse_view)
1ffb8e 304
8c2a9e 305     def test_ctor_exceptionresponse_view_None(self):
CM 306         from pyramid.interfaces import IExceptionResponse
0c29cf 307
8c2a9e 308         config = self._makeOne(exceptionresponse_view=None)
0c29cf 309         view = self._getViewCallable(
MM 310             config, ctx_iface=IExceptionResponse, request_iface=IRequest
311         )
366a5c 312         self.assertTrue(view is None)
1ffb8e 313
8c2a9e 314     def test_ctor_exceptionresponse_view_custom(self):
CM 315         from pyramid.interfaces import IExceptionResponse
0c29cf 316
10ddb6 317         def exceptionresponse_view(context, request):  # pragma: no cover
0c29cf 318             pass
MM 319
8c2a9e 320         config = self._makeOne(exceptionresponse_view=exceptionresponse_view)
0c29cf 321         view = self._getViewCallable(
MM 322             config, ctx_iface=IExceptionResponse, request_iface=IRequest
323         )
58bc25 324         self.assertTrue(view.__wraps__ is exceptionresponse_view)
1ffb8e 325
844ed9 326     def test_ctor_with_introspection(self):
CM 327         config = self._makeOne(introspection=False)
328         self.assertEqual(config.introspection, False)
2e651e 329
27190e 330     def test_ctor_default_webob_response_adapter_registered(self):
CM 331         from webob import Response as WebobResponse
0c29cf 332
27190e 333         response = WebobResponse()
CM 334         from pyramid.interfaces import IResponse
0c29cf 335
27190e 336         config = self._makeOne(autocommit=True)
CM 337         result = config.registry.queryAdapter(response, IResponse)
338         self.assertEqual(result, response)
0c29cf 339
427a02 340     def test_with_package_module(self):
dd3cc8 341         from . import test_init
0c29cf 342
427a02 343         config = self._makeOne()
1aeae3 344         newconfig = config.with_package(test_init)
dd3cc8 345         import tests.test_config
0c29cf 346
dd3cc8 347         self.assertEqual(newconfig.package, tests.test_config)
427a02 348
CM 349     def test_with_package_package(self):
dd3cc8 350         from tests import test_config
0c29cf 351
427a02 352         config = self._makeOne()
dd3cc8 353         newconfig = config.with_package(test_config)
MM 354         self.assertEqual(newconfig.package, test_config)
427a02 355
b86fa9 356     def test_with_package(self):
dd3cc8 357         import tests
0c29cf 358
865c1d 359         config = self._makeOne()
b86fa9 360         config.basepath = 'basepath'
CM 361         config.info = 'info'
362         config.includepath = ('spec',)
363         config.autocommit = True
364         config.route_prefix = 'prefix'
dd3cc8 365         newconfig = config.with_package(tests)
MM 366         self.assertEqual(newconfig.package, tests)
b86fa9 367         self.assertEqual(newconfig.registry, config.registry)
CM 368         self.assertEqual(newconfig.autocommit, True)
369         self.assertEqual(newconfig.route_prefix, 'prefix')
370         self.assertEqual(newconfig.info, 'info')
371         self.assertEqual(newconfig.basepath, 'basepath')
372         self.assertEqual(newconfig.includepath, ('spec',))
eb2a57 373
427a02 374     def test_maybe_dotted_string_success(self):
dd3cc8 375         import tests.test_config
0c29cf 376
427a02 377         config = self._makeOne()
dd3cc8 378         result = config.maybe_dotted('tests.test_config')
MM 379         self.assertEqual(result, tests.test_config)
427a02 380
CM 381     def test_maybe_dotted_string_fail(self):
382         config = self._makeOne()
79ef3d 383         self.assertRaises(ImportError, config.maybe_dotted, 'cant.be.found')
427a02 384
CM 385     def test_maybe_dotted_notstring_success(self):
dd3cc8 386         import tests.test_config
0c29cf 387
427a02 388         config = self._makeOne()
dd3cc8 389         result = config.maybe_dotted(tests.test_config)
MM 390         self.assertEqual(result, tests.test_config)
427a02 391
92c3e5 392     def test_absolute_asset_spec_already_absolute(self):
dd3cc8 393         import tests.test_config
0c29cf 394
dd3cc8 395         config = self._makeOne(package=tests.test_config)
92c3e5 396         result = config.absolute_asset_spec('already:absolute')
427a02 397         self.assertEqual(result, 'already:absolute')
CM 398
92c3e5 399     def test_absolute_asset_spec_notastring(self):
dd3cc8 400         import tests.test_config
0c29cf 401
dd3cc8 402         config = self._makeOne(package=tests.test_config)
92c3e5 403         result = config.absolute_asset_spec(None)
427a02 404         self.assertEqual(result, None)
CM 405
92c3e5 406     def test_absolute_asset_spec_relative(self):
dd3cc8 407         import tests.test_config
0c29cf 408
dd3cc8 409         config = self._makeOne(package=tests.test_config)
1aeae3 410         result = config.absolute_asset_spec('files')
dd3cc8 411         self.assertEqual(result, 'tests.test_config:files')
427a02 412
d868ff 413     def test__fix_registry_has_listeners(self):
CM 414         reg = DummyRegistry()
415         config = self._makeOne(reg)
416         config._fix_registry()
417         self.assertEqual(reg.has_listeners, True)
418
419     def test__fix_registry_notify(self):
420         reg = DummyRegistry()
421         config = self._makeOne(reg)
422         config._fix_registry()
423         self.assertEqual(reg.notify(1), None)
424         self.assertEqual(reg.events, (1,))
425
426     def test__fix_registry_queryAdapterOrSelf(self):
427         from zope.interface import Interface
3b7334 428         from zope.interface import implementer
0c29cf 429
d868ff 430         class IFoo(Interface):
CM 431             pass
0c29cf 432
3b7334 433         @implementer(IFoo)
d868ff 434         class Foo(object):
3b7334 435             pass
0c29cf 436
d868ff 437         class Bar(object):
CM 438             pass
0c29cf 439
d868ff 440         adaptation = ()
CM 441         foo = Foo()
442         bar = Bar()
443         reg = DummyRegistry(adaptation)
444         config = self._makeOne(reg)
445         config._fix_registry()
446         self.assertTrue(reg.queryAdapterOrSelf(foo, IFoo) is foo)
447         self.assertTrue(reg.queryAdapterOrSelf(bar, IFoo) is adaptation)
448
449     def test__fix_registry_registerSelfAdapter(self):
450         reg = DummyRegistry()
451         config = self._makeOne(reg)
452         config._fix_registry()
453         reg.registerSelfAdapter('required', 'provided', name='abc')
454         self.assertEqual(len(reg.adapters), 1)
455         args, kw = reg.adapters[0]
456         self.assertEqual(args[0]('abc'), 'abc')
0c29cf 457         self.assertEqual(
MM 458             kw,
459             {
460                 'info': '',
461                 'provided': 'provided',
462                 'required': 'required',
463                 'name': 'abc',
464                 'event': True,
465             },
466         )
d868ff 467
c15cbc 468     def test__fix_registry_adds__lock(self):
CM 469         reg = DummyRegistry()
470         config = self._makeOne(reg)
471         config._fix_registry()
472         self.assertTrue(hasattr(reg, '_lock'))
473
474     def test__fix_registry_adds_clear_view_lookup_cache(self):
475         reg = DummyRegistry()
476         config = self._makeOne(reg)
477         self.assertFalse(hasattr(reg, '_clear_view_lookup_cache'))
478         config._fix_registry()
479         self.assertFalse(hasattr(reg, '_view_lookup_cache'))
480         reg._clear_view_lookup_cache()
481         self.assertEqual(reg._view_lookup_cache, {})
482
d868ff 483     def test_setup_registry_calls_fix_registry(self):
427a02 484         reg = DummyRegistry()
CM 485         config = self._makeOne(reg)
486         config.add_view = lambda *arg, **kw: False
b4843b 487         config._add_tween = lambda *arg, **kw: False
427a02 488         config.setup_registry()
CM 489         self.assertEqual(reg.has_listeners, True)
490
a00621 491     def test_setup_registry_registers_default_exceptionresponse_views(self):
d69ae6 492         from webob.exc import WSGIHTTPException
427a02 493         from pyramid.interfaces import IExceptionResponse
CM 494         from pyramid.view import default_exceptionresponse_view
0c29cf 495
427a02 496         reg = DummyRegistry()
CM 497         config = self._makeOne(reg)
498         views = []
499         config.add_view = lambda *arg, **kw: views.append((arg, kw))
a00621 500         config.add_default_view_predicates = lambda *arg: None
b4843b 501         config._add_tween = lambda *arg, **kw: False
427a02 502         config.setup_registry()
0c29cf 503         self.assertEqual(
MM 504             views[0],
505             (
506                 (default_exceptionresponse_view,),
507                 {'context': IExceptionResponse},
508             ),
509         )
510         self.assertEqual(
511             views[1],
512             (
513                 (default_exceptionresponse_view,),
514                 {'context': WSGIHTTPException},
515             ),
516         )
a00621 517
CM 518     def test_setup_registry_registers_default_view_predicates(self):
519         reg = DummyRegistry()
520         config = self._makeOne(reg)
521         vp_called = []
522         config.add_view = lambda *arg, **kw: None
0c29cf 523         config.add_default_view_predicates = lambda *arg: vp_called.append(
MM 524             True
525         )
a00621 526         config._add_tween = lambda *arg, **kw: False
CM 527         config.setup_registry()
528         self.assertTrue(vp_called)
d868ff 529
CM 530     def test_setup_registry_registers_default_webob_iresponse_adapter(self):
531         from webob import Response
532         from pyramid.interfaces import IResponse
0c29cf 533
d868ff 534         config = self._makeOne()
CM 535         config.setup_registry()
536         response = Response()
537         self.assertTrue(
0c29cf 538             config.registry.queryAdapter(response, IResponse) is response
MM 539         )
1ffb8e 540
427a02 541     def test_setup_registry_explicit_notfound_trumps_iexceptionresponse(self):
aa2fe1 542         from pyramid.renderers import null_renderer
427a02 543         from zope.interface import implementedBy
99edc5 544         from pyramid.httpexceptions import HTTPNotFound
427a02 545         from pyramid.registry import Registry
0c29cf 546
427a02 547         reg = Registry()
CM 548         config = self._makeOne(reg, autocommit=True)
0c29cf 549         config.setup_registry()  # registers IExceptionResponse default view
MM 550
427a02 551         def myview(context, request):
CM 552             return 'OK'
0c29cf 553
aa2fe1 554         config.add_view(myview, context=HTTPNotFound, renderer=null_renderer)
427a02 555         request = self._makeRequest(config)
0c29cf 556         view = self._getViewCallable(
MM 557             config,
558             ctx_iface=implementedBy(HTTPNotFound),
559             request_iface=IRequest,
560         )
427a02 561         result = view(None, request)
CM 562         self.assertEqual(result, 'OK')
563
564     def test_setup_registry_custom_settings(self):
565         from pyramid.registry import Registry
566         from pyramid.interfaces import ISettings
0c29cf 567
MM 568         settings = {'reload_templates': True, 'mysetting': True}
427a02 569         reg = Registry()
CM 570         config = self._makeOne(reg)
571         config.setup_registry(settings=settings)
572         settings = reg.getUtility(ISettings)
573         self.assertEqual(settings['reload_templates'], True)
574         self.assertEqual(settings['debug_authorization'], False)
575         self.assertEqual(settings['mysetting'], True)
576
577     def test_setup_registry_debug_logger_None_default(self):
578         from pyramid.registry import Registry
579         from pyramid.interfaces import IDebugLogger
0c29cf 580
427a02 581         reg = Registry()
CM 582         config = self._makeOne(reg)
583         config.setup_registry()
584         logger = reg.getUtility(IDebugLogger)
dd3cc8 585         self.assertEqual(logger.name, 'tests.test_config')
427a02 586
CM 587     def test_setup_registry_debug_logger_non_None(self):
588         from pyramid.registry import Registry
589         from pyramid.interfaces import IDebugLogger
0c29cf 590
427a02 591         logger = object()
CM 592         reg = Registry()
593         config = self._makeOne(reg)
594         config.setup_registry(debug_logger=logger)
595         result = reg.getUtility(IDebugLogger)
596         self.assertEqual(logger, result)
597
3a8054 598     def test_setup_registry_debug_logger_name(self):
427a02 599         from pyramid.registry import Registry
CM 600         from pyramid.interfaces import IDebugLogger
0c29cf 601
427a02 602         reg = Registry()
CM 603         config = self._makeOne(reg)
3a8054 604         config.setup_registry(debug_logger='foo')
427a02 605         result = reg.getUtility(IDebugLogger)
3a8054 606         self.assertEqual(result.name, 'foo')
427a02 607
CM 608     def test_setup_registry_authentication_policy(self):
609         from pyramid.registry import Registry
610         from pyramid.interfaces import IAuthenticationPolicy
0c29cf 611
427a02 612         policy = object()
CM 613         reg = Registry()
614         config = self._makeOne(reg)
615         config.setup_registry(authentication_policy=policy)
f67ba4 616         config.commit()
427a02 617         result = reg.getUtility(IAuthenticationPolicy)
CM 618         self.assertEqual(policy, result)
619
620     def test_setup_registry_authentication_policy_dottedname(self):
621         from pyramid.registry import Registry
622         from pyramid.interfaces import IAuthenticationPolicy
0c29cf 623
427a02 624         reg = Registry()
CM 625         config = self._makeOne(reg)
dd3cc8 626         config.setup_registry(authentication_policy='tests.test_config')
f67ba4 627         config.commit()
427a02 628         result = reg.getUtility(IAuthenticationPolicy)
dd3cc8 629         import tests.test_config
0c29cf 630
dd3cc8 631         self.assertEqual(result, tests.test_config)
427a02 632
CM 633     def test_setup_registry_authorization_policy_dottedname(self):
634         from pyramid.registry import Registry
635         from pyramid.interfaces import IAuthorizationPolicy
0c29cf 636
427a02 637         reg = Registry()
CM 638         config = self._makeOne(reg)
639         dummy = object()
0c29cf 640         config.setup_registry(
MM 641             authentication_policy=dummy,
642             authorization_policy='tests.test_config',
643         )
f67ba4 644         config.commit()
427a02 645         result = reg.getUtility(IAuthorizationPolicy)
dd3cc8 646         import tests.test_config
0c29cf 647
dd3cc8 648         self.assertEqual(result, tests.test_config)
427a02 649
CM 650     def test_setup_registry_authorization_policy_only(self):
651         from pyramid.registry import Registry
0c29cf 652
427a02 653         policy = object()
CM 654         reg = Registry()
655         config = self._makeOne(reg)
ea824f 656         config.setup_registry(authorization_policy=policy)
CM 657         config = self.assertRaises(ConfigurationExecutionError, config.commit)
427a02 658
2a818a 659     def test_setup_registry_no_default_root_factory(self):
427a02 660         from pyramid.registry import Registry
CM 661         from pyramid.interfaces import IRootFactory
0c29cf 662
427a02 663         reg = Registry()
CM 664         config = self._makeOne(reg)
665         config.setup_registry()
ea824f 666         config.commit()
2a818a 667         self.assertEqual(reg.queryUtility(IRootFactory), None)
427a02 668
CM 669     def test_setup_registry_dottedname_root_factory(self):
670         from pyramid.registry import Registry
671         from pyramid.interfaces import IRootFactory
0c29cf 672
427a02 673         reg = Registry()
CM 674         config = self._makeOne(reg)
dd3cc8 675         import tests.test_config
0c29cf 676
dd3cc8 677         config.setup_registry(root_factory='tests.test_config')
ea824f 678         self.assertEqual(reg.queryUtility(IRootFactory), None)
CM 679         config.commit()
dd3cc8 680         self.assertEqual(reg.getUtility(IRootFactory), tests.test_config)
427a02 681
CM 682     def test_setup_registry_locale_negotiator_dottedname(self):
683         from pyramid.registry import Registry
684         from pyramid.interfaces import ILocaleNegotiator
0c29cf 685
427a02 686         reg = Registry()
CM 687         config = self._makeOne(reg)
dd3cc8 688         import tests.test_config
0c29cf 689
dd3cc8 690         config.setup_registry(locale_negotiator='tests.test_config')
ea824f 691         self.assertEqual(reg.queryUtility(ILocaleNegotiator), None)
CM 692         config.commit()
427a02 693         utility = reg.getUtility(ILocaleNegotiator)
dd3cc8 694         self.assertEqual(utility, tests.test_config)
427a02 695
CM 696     def test_setup_registry_locale_negotiator(self):
697         from pyramid.registry import Registry
698         from pyramid.interfaces import ILocaleNegotiator
0c29cf 699
427a02 700         reg = Registry()
CM 701         config = self._makeOne(reg)
702         negotiator = object()
703         config.setup_registry(locale_negotiator=negotiator)
ea824f 704         self.assertEqual(reg.queryUtility(ILocaleNegotiator), None)
CM 705         config.commit()
427a02 706         utility = reg.getUtility(ILocaleNegotiator)
CM 707         self.assertEqual(utility, negotiator)
708
709     def test_setup_registry_request_factory(self):
710         from pyramid.registry import Registry
711         from pyramid.interfaces import IRequestFactory
0c29cf 712
427a02 713         reg = Registry()
CM 714         config = self._makeOne(reg)
715         factory = object()
716         config.setup_registry(request_factory=factory)
ea824f 717         self.assertEqual(reg.queryUtility(IRequestFactory), None)
CM 718         config.commit()
427a02 719         utility = reg.getUtility(IRequestFactory)
CM 720         self.assertEqual(utility, factory)
721
1236de 722     def test_setup_registry_response_factory(self):
JA 723         from pyramid.registry import Registry
724         from pyramid.interfaces import IResponseFactory
0c29cf 725
1236de 726         reg = Registry()
JA 727         config = self._makeOne(reg)
32cb80 728         factory = lambda r: object()
1236de 729         config.setup_registry(response_factory=factory)
JA 730         self.assertEqual(reg.queryUtility(IResponseFactory), None)
731         config.commit()
732         utility = reg.getUtility(IResponseFactory)
733         self.assertEqual(utility, factory)
367ffe 734
427a02 735     def test_setup_registry_request_factory_dottedname(self):
CM 736         from pyramid.registry import Registry
737         from pyramid.interfaces import IRequestFactory
0c29cf 738
427a02 739         reg = Registry()
CM 740         config = self._makeOne(reg)
dd3cc8 741         import tests.test_config
0c29cf 742
dd3cc8 743         config.setup_registry(request_factory='tests.test_config')
ea824f 744         self.assertEqual(reg.queryUtility(IRequestFactory), None)
CM 745         config.commit()
427a02 746         utility = reg.getUtility(IRequestFactory)
dd3cc8 747         self.assertEqual(utility, tests.test_config)
427a02 748
CM 749     def test_setup_registry_alternate_renderers(self):
750         from pyramid.registry import Registry
751         from pyramid.interfaces import IRendererFactory
0c29cf 752
427a02 753         renderer = object()
CM 754         reg = Registry()
755         config = self._makeOne(reg)
756         config.setup_registry(renderers=[('yeah', renderer)])
f67ba4 757         config.commit()
0c29cf 758         self.assertEqual(reg.getUtility(IRendererFactory, 'yeah'), renderer)
427a02 759
CM 760     def test_setup_registry_default_permission(self):
761         from pyramid.registry import Registry
762         from pyramid.interfaces import IDefaultPermission
0c29cf 763
427a02 764         reg = Registry()
CM 765         config = self._makeOne(reg)
766         config.setup_registry(default_permission='view')
f67ba4 767         config.commit()
427a02 768         self.assertEqual(reg.getUtility(IDefaultPermission), 'view')
CM 769
1a45b4 770     def test_setup_registry_includes(self):
MM 771         from pyramid.registry import Registry
0c29cf 772
1a45b4 773         reg = Registry()
MM 774         config = self._makeOne(reg)
775         settings = {
0c29cf 776             'pyramid.includes': """tests.test_config.dummy_include
MM 777 tests.test_config.dummy_include2"""
1a45b4 778         }
MM 779         config.setup_registry(settings=settings)
fd266a 780         self.assertTrue(reg.included)
CM 781         self.assertTrue(reg.also_included)
1a45b4 782
8cd013 783     def test_setup_registry_includes_spaces(self):
CM 784         from pyramid.registry import Registry
0c29cf 785
8cd013 786         reg = Registry()
CM 787         config = self._makeOne(reg)
788         settings = {
10ddb6 789             'pyramid.includes': """tests.test_config.dummy_include tests.\
MM 790 test_config.dummy_include2"""
8cd013 791         }
CM 792         config.setup_registry(settings=settings)
fd266a 793         self.assertTrue(reg.included)
CM 794         self.assertTrue(reg.also_included)
8cd013 795
feabd3 796     def test_setup_registry_tweens(self):
CM 797         from pyramid.interfaces import ITweens
798         from pyramid.registry import Registry
0c29cf 799
feabd3 800         reg = Registry()
CM 801         config = self._makeOne(reg)
0c29cf 802         settings = {'pyramid.tweens': 'tests.test_config.dummy_tween_factory'}
feabd3 803         config.setup_registry(settings=settings)
8517d4 804         config.commit()
feabd3 805         tweens = config.registry.getUtility(ITweens)
5bf23f 806         self.assertEqual(
CM 807             tweens.explicit,
0c29cf 808             [('tests.test_config.dummy_tween_factory', dummy_tween_factory)],
MM 809         )
feabd3 810
2e651e 811     def test_introspector_decorator(self):
CM 812         inst = self._makeOne()
813         default = inst.introspector
4e6afc 814         self.assertTrue(hasattr(default, 'add'))
2e651e 815         self.assertEqual(inst.introspector, inst.registry.introspector)
844ed9 816         introspector = object()
2e651e 817         inst.introspector = introspector
CM 818         new = inst.introspector
4e6afc 819         self.assertTrue(new is introspector)
2e651e 820         self.assertEqual(inst.introspector, inst.registry.introspector)
CM 821         del inst.introspector
822         default = inst.introspector
4e6afc 823         self.assertFalse(default is new)
CM 824         self.assertTrue(hasattr(default, 'add'))
2e651e 825
427a02 826     def test_make_wsgi_app(self):
68d12c 827         import pyramid.config
427a02 828         from pyramid.router import Router
CM 829         from pyramid.interfaces import IApplicationCreated
0c29cf 830
427a02 831         manager = DummyThreadLocalManager()
CM 832         config = self._makeOne()
833         subscriber = self._registerEventListener(config, IApplicationCreated)
834         config.manager = manager
835         app = config.make_wsgi_app()
836         self.assertEqual(app.__class__, Router)
837         self.assertEqual(manager.pushed['registry'], config.registry)
838         self.assertEqual(manager.pushed['request'], None)
a1d395 839         self.assertTrue(manager.popped)
981c05 840         self.assertEqual(pyramid.config.global_registries.last, app.registry)
427a02 841         self.assertEqual(len(subscriber), 1)
a1d395 842         self.assertTrue(IApplicationCreated.providedBy(subscriber[0]))
eff1cb 843         pyramid.config.global_registries.empty()
427a02 844
CM 845     def test_include_with_dotted_name(self):
dd3cc8 846         from tests import test_config
0c29cf 847
427a02 848         config = self._makeOne()
dd3cc8 849         config.include('tests.test_config.dummy_include')
b86fa9 850         after = config.action_state
CM 851         actions = after.actions
427a02 852         self.assertEqual(len(actions), 1)
412b4a 853         action = after.actions[0]
CM 854         self.assertEqual(action['discriminator'], 'discrim')
855         self.assertEqual(action['callable'], None)
856         self.assertEqual(action['args'], test_config)
427a02 857
CM 858     def test_include_with_python_callable(self):
dd3cc8 859         from tests import test_config
0c29cf 860
427a02 861         config = self._makeOne()
CM 862         config.include(dummy_include)
b86fa9 863         after = config.action_state
CM 864         actions = after.actions
427a02 865         self.assertEqual(len(actions), 1)
412b4a 866         action = actions[0]
CM 867         self.assertEqual(action['discriminator'], 'discrim')
868         self.assertEqual(action['callable'], None)
869         self.assertEqual(action['args'], test_config)
427a02 870
08170a 871     def test_include_with_module_defaults_to_includeme(self):
dd3cc8 872         from tests import test_config
0c29cf 873
08170a 874         config = self._makeOne()
dd3cc8 875         config.include('tests.test_config')
b86fa9 876         after = config.action_state
CM 877         actions = after.actions
08170a 878         self.assertEqual(len(actions), 1)
412b4a 879         action = actions[0]
CM 880         self.assertEqual(action['discriminator'], 'discrim')
881         self.assertEqual(action['callable'], None)
882         self.assertEqual(action['args'], test_config)
0b13e1 883
f8bfc6 884     def test_include_with_module_defaults_to_includeme_missing(self):
CM 885         from pyramid.exceptions import ConfigurationError
0c29cf 886
f8bfc6 887         config = self._makeOne()
dd3cc8 888         self.assertRaises(ConfigurationError, config.include, 'tests')
f8bfc6 889
0b13e1 890     def test_include_with_route_prefix(self):
MM 891         root_config = self._makeOne(autocommit=True)
0c29cf 892
0b13e1 893         def dummy_subapp(config):
MM 894             self.assertEqual(config.route_prefix, 'root')
0c29cf 895
0b13e1 896         root_config.include(dummy_subapp, route_prefix='root')
MM 897
898     def test_include_with_nested_route_prefix(self):
899         root_config = self._makeOne(autocommit=True, route_prefix='root')
0c29cf 900
7a7c8c 901         def dummy_subapp2(config):
CM 902             self.assertEqual(config.route_prefix, 'root/nested')
0c29cf 903
7a7c8c 904         def dummy_subapp3(config):
CM 905             self.assertEqual(config.route_prefix, 'root/nested/nested2')
906             config.include(dummy_subapp4)
0c29cf 907
7a7c8c 908         def dummy_subapp4(config):
CM 909             self.assertEqual(config.route_prefix, 'root/nested/nested2')
0c29cf 910
0b13e1 911         def dummy_subapp(config):
MM 912             self.assertEqual(config.route_prefix, 'root/nested')
7a7c8c 913             config.include(dummy_subapp2)
CM 914             config.include(dummy_subapp3, route_prefix='nested2')
915
0b13e1 916         root_config.include(dummy_subapp, route_prefix='nested')
08170a 917
5ad401 918     def test_include_with_missing_source_file(self):
CM 919         from pyramid.exceptions import ConfigurationError
920         import inspect
0c29cf 921
5ad401 922         config = self._makeOne()
0c29cf 923
5ad401 924         class DummyInspect(object):
CM 925             def getmodule(self, c):
926                 return inspect.getmodule(c)
0c29cf 927
5ad401 928             def getsourcefile(self, c):
CM 929                 return None
0c29cf 930
5ad401 931         config.inspect = DummyInspect()
CM 932         try:
dd3cc8 933             config.include('tests.test_config.dummy_include')
5ad401 934         except ConfigurationError as e:
CM 935             self.assertEqual(
0c29cf 936                 e.args[0],
dd3cc8 937                 "No source file for module 'tests.test_config' (.py "
0c29cf 938                 "file must exist, refusing to use orphan .pyc or .pyo file).",
MM 939             )
940         else:  # pragma: no cover
5ad401 941             raise AssertionError
f5bafd 942
ae6c88 943     def test_include_constant_root_package(self):
dd3cc8 944         import tests
MM 945         from tests import test_config
0c29cf 946
ae6c88 947         config = self._makeOne(root_package=tests)
MM 948         results = {}
0c29cf 949
ae6c88 950         def include(config):
MM 951             results['package'] = config.package
952             results['root_package'] = config.root_package
0c29cf 953
ae6c88 954         config.include(include)
MM 955         self.assertEqual(results['root_package'], tests)
956         self.assertEqual(results['package'], test_config)
957
a857eb 958     def test_include_threadlocals_active(self):
MM 959         from pyramid.threadlocal import get_current_registry
0c29cf 960
a857eb 961         stack = []
0c29cf 962
a857eb 963         def include(config):
MM 964             stack.append(get_current_registry())
0c29cf 965
a857eb 966         config = self._makeOne()
MM 967         config.include(include)
968         self.assertTrue(stack[0] is config.registry)
969
427a02 970     def test_scan_integration(self):
CM 971         from zope.interface import alsoProvides
972         from pyramid.view import render_view_to_response
dd3cc8 973         import tests.test_config.pkgs.scannable as package
0c29cf 974
427a02 975         config = self._makeOne(autocommit=True)
CM 976         config.scan(package)
977
978         ctx = DummyContext()
979         req = DummyRequest()
980         alsoProvides(req, IRequest)
981         req.registry = config.registry
982
983         req.method = 'GET'
984         result = render_view_to_response(ctx, req, '')
985         self.assertEqual(result, 'grokked')
986
987         req.method = 'POST'
988         result = render_view_to_response(ctx, req, '')
989         self.assertEqual(result, 'grokked_post')
990
0c29cf 991         result = render_view_to_response(ctx, req, 'grokked_class')
427a02 992         self.assertEqual(result, 'grokked_class')
CM 993
0c29cf 994         result = render_view_to_response(ctx, req, 'grokked_instance')
427a02 995         self.assertEqual(result, 'grokked_instance')
CM 996
0c29cf 997         result = render_view_to_response(ctx, req, 'oldstyle_grokked_class')
427a02 998         self.assertEqual(result, 'oldstyle_grokked_class')
CM 999
1000         req.method = 'GET'
1001         result = render_view_to_response(ctx, req, 'another')
1002         self.assertEqual(result, 'another_grokked')
1003
1004         req.method = 'POST'
1005         result = render_view_to_response(ctx, req, 'another')
1006         self.assertEqual(result, 'another_grokked_post')
1007
0c29cf 1008         result = render_view_to_response(ctx, req, 'another_grokked_class')
427a02 1009         self.assertEqual(result, 'another_grokked_class')
CM 1010
0c29cf 1011         result = render_view_to_response(ctx, req, 'another_grokked_instance')
427a02 1012         self.assertEqual(result, 'another_grokked_instance')
CM 1013
0c29cf 1014         result = render_view_to_response(
MM 1015             ctx, req, 'another_oldstyle_grokked_class'
1016         )
427a02 1017         self.assertEqual(result, 'another_oldstyle_grokked_class')
CM 1018
1019         result = render_view_to_response(ctx, req, 'stacked1')
1020         self.assertEqual(result, 'stacked')
1021
1022         result = render_view_to_response(ctx, req, 'stacked2')
1023         self.assertEqual(result, 'stacked')
1024
1025         result = render_view_to_response(ctx, req, 'another_stacked1')
1026         self.assertEqual(result, 'another_stacked')
1027
1028         result = render_view_to_response(ctx, req, 'another_stacked2')
1029         self.assertEqual(result, 'another_stacked')
1030
1031         result = render_view_to_response(ctx, req, 'stacked_class1')
1032         self.assertEqual(result, 'stacked_class')
1033
1034         result = render_view_to_response(ctx, req, 'stacked_class2')
1035         self.assertEqual(result, 'stacked_class')
1036
1037         result = render_view_to_response(ctx, req, 'another_stacked_class1')
1038         self.assertEqual(result, 'another_stacked_class')
1039
1040         result = render_view_to_response(ctx, req, 'another_stacked_class2')
1041         self.assertEqual(result, 'another_stacked_class')
1042
1c7724 1043         # NB: on Jython, a class without an __init__ apparently accepts
CM 1044         # any number of arguments without raising a TypeError, so the next
1045         # assertion may fail there.  We don't support Jython at the moment,
1046         # this is just a note to a future self.
427a02 1047
0c29cf 1048         self.assertRaises(
MM 1049             TypeError, render_view_to_response, ctx, req, 'basemethod'
1050         )
427a02 1051
CM 1052         result = render_view_to_response(ctx, req, 'method1')
1053         self.assertEqual(result, 'method1')
1054
1055         result = render_view_to_response(ctx, req, 'method2')
1056         self.assertEqual(result, 'method2')
1057
1058         result = render_view_to_response(ctx, req, 'stacked_method1')
1059         self.assertEqual(result, 'stacked_method')
1060
1061         result = render_view_to_response(ctx, req, 'stacked_method2')
1062         self.assertEqual(result, 'stacked_method')
1063
1064         result = render_view_to_response(ctx, req, 'subpackage_init')
1065         self.assertEqual(result, 'subpackage_init')
1066
1067         result = render_view_to_response(ctx, req, 'subpackage_notinit')
1068         self.assertEqual(result, 'subpackage_notinit')
1069
1070         result = render_view_to_response(ctx, req, 'subsubpackage_init')
1071         self.assertEqual(result, 'subsubpackage_init')
1072
1073         result = render_view_to_response(ctx, req, 'pod_notinit')
1074         self.assertEqual(result, None)
1075
e4b8fa 1076     def test_scan_integration_with_ignore(self):
CM 1077         from zope.interface import alsoProvides
1078         from pyramid.view import render_view_to_response
dd3cc8 1079         import tests.test_config.pkgs.scannable as package
0c29cf 1080
e4b8fa 1081         config = self._makeOne(autocommit=True)
0c29cf 1082         config.scan(package, ignore='tests.test_config.pkgs.scannable.another')
e4b8fa 1083
CM 1084         ctx = DummyContext()
1085         req = DummyRequest()
1086         alsoProvides(req, IRequest)
1087         req.registry = config.registry
1088
1089         req.method = 'GET'
1090         result = render_view_to_response(ctx, req, '')
1091         self.assertEqual(result, 'grokked')
1092
1093         # ignored
1094         v = render_view_to_response(ctx, req, 'another_stacked_class2')
1095         self.assertEqual(v, None)
0c29cf 1096
427a02 1097     def test_scan_integration_dottedname_package(self):
CM 1098         from zope.interface import alsoProvides
1099         from pyramid.view import render_view_to_response
0c29cf 1100
427a02 1101         config = self._makeOne(autocommit=True)
dd3cc8 1102         config.scan('tests.test_config.pkgs.scannable')
427a02 1103
CM 1104         ctx = DummyContext()
1105         req = DummyRequest()
1106         alsoProvides(req, IRequest)
1107         req.registry = config.registry
1108
1109         req.method = 'GET'
1110         result = render_view_to_response(ctx, req, '')
1111         self.assertEqual(result, 'grokked')
1112
fca1ef 1113     def test_scan_integration_with_extra_kw(self):
CM 1114         config = self._makeOne(autocommit=True)
dd3cc8 1115         config.scan('tests.test_config.pkgs.scanextrakw', a=1)
fca1ef 1116         self.assertEqual(config.a, 1)
1aeae3 1117
CM 1118     def test_scan_integration_with_onerror(self):
1119         # fancy sys.path manipulation here to appease "setup.py test" which
1120         # fails miserably when it can't import something in the package
1121         import sys
0c29cf 1122
1aeae3 1123         try:
CM 1124             here = os.path.dirname(__file__)
1125             path = os.path.join(here, 'path')
1126             sys.path.append(path)
1127             config = self._makeOne(autocommit=True)
0c29cf 1128
1aeae3 1129             class FooException(Exception):
CM 1130                 pass
0c29cf 1131
1aeae3 1132             def onerror(name):
CM 1133                 raise FooException
0c29cf 1134
MM 1135             self.assertRaises(
1136                 FooException, config.scan, 'scanerror', onerror=onerror
1137             )
1aeae3 1138         finally:
CM 1139             sys.path.remove(path)
1140
1141     def test_scan_integration_conflict(self):
dd3cc8 1142         from tests.test_config.pkgs import selfscan
1aeae3 1143         from pyramid.config import Configurator
0c29cf 1144
1aeae3 1145         c = Configurator()
CM 1146         c.scan(selfscan)
1147         c.scan(selfscan)
1148         try:
1149             c.commit()
8e606d 1150         except ConfigurationConflictError as why:
0c29cf 1151
1aeae3 1152             def scanconflicts(e):
CM 1153                 conflicts = e._conflicts.values()
1154                 for conflict in conflicts:
1155                     for confinst in conflict:
4a4ef4 1156                         yield confinst.src
0c29cf 1157
1aeae3 1158             which = list(scanconflicts(why))
CM 1159             self.assertEqual(len(which), 4)
1160             self.assertTrue("@view_config(renderer='string')" in which)
0c29cf 1161             self.assertTrue(
MM 1162                 "@view_config(name='two', renderer='string')" in which
1163             )
1aeae3 1164
fbd01a 1165     @skip_on('py3')
427a02 1166     def test_hook_zca(self):
865c1d 1167         from zope.component import getSiteManager
0c29cf 1168
865c1d 1169         def foo():
CM 1170             '123'
0c29cf 1171
865c1d 1172         try:
CM 1173             config = self._makeOne()
1174             config.hook_zca()
1175             config.begin()
1176             sm = getSiteManager()
1177             self.assertEqual(sm, config.registry)
1178         finally:
1179             getSiteManager.reset()
427a02 1180
fbd01a 1181     @skip_on('py3')
427a02 1182     def test_unhook_zca(self):
865c1d 1183         from zope.component import getSiteManager
0c29cf 1184
865c1d 1185         def foo():
CM 1186             '123'
0c29cf 1187
865c1d 1188         try:
CM 1189             getSiteManager.sethook(foo)
1190             config = self._makeOne()
1191             config.unhook_zca()
1192             sm = getSiteManager()
1193             self.assertNotEqual(sm, '123')
1194         finally:
1195             getSiteManager.reset()
af46cf 1196
e333c2 1197     def test___getattr__missing_when_directives_exist(self):
CM 1198         config = self._makeOne()
1199         directives = {}
1200         config.registry._directives = directives
1201         self.assertRaises(AttributeError, config.__getattr__, 'wontexist')
1202
1203     def test___getattr__missing_when_directives_dont_exist(self):
1204         config = self._makeOne()
1205         self.assertRaises(AttributeError, config.__getattr__, 'wontexist')
1206
1207     def test___getattr__matches(self):
1208         config = self._makeOne()
0c29cf 1209
10ddb6 1210         def foo(config):  # pragma: no cover
0c29cf 1211             pass
MM 1212
1213         directives = {'foo': (foo, True)}
e333c2 1214         config.registry._directives = directives
CM 1215         foo_meth = config.foo
fbd01a 1216         self.assertTrue(getattr(foo_meth, im_func).__docobj__ is foo)
af46cf 1217
bb741d 1218     def test___getattr__matches_no_action_wrap(self):
CM 1219         config = self._makeOne()
0c29cf 1220
10ddb6 1221         def foo(config):  # pragma: no cover
0c29cf 1222             pass
MM 1223
1224         directives = {'foo': (foo, False)}
bb741d 1225         config.registry._directives = directives
CM 1226         foo_meth = config.foo
fbd01a 1227         self.assertTrue(getattr(foo_meth, im_func) is foo)
bb741d 1228
cad4e3 1229
0c29cf 1230 class TestConfigurator_add_directive(unittest.TestCase):
cad4e3 1231     def setUp(self):
GP 1232         from pyramid.config import Configurator
0c29cf 1233
2422ce 1234         self.config = Configurator()
cad4e3 1235
GP 1236     def test_extend_with_dotted_name(self):
dd3cc8 1237         from tests import test_config
0c29cf 1238
cad4e3 1239         config = self.config
0c29cf 1240         config.add_directive('dummy_extend', 'tests.test_config.dummy_extend')
fbd01a 1241         self.assertTrue(hasattr(config, 'dummy_extend'))
cad4e3 1242         config.dummy_extend('discrim')
b86fa9 1243         after = config.action_state
412b4a 1244         action = after.actions[-1]
CM 1245         self.assertEqual(action['discriminator'], 'discrim')
1246         self.assertEqual(action['callable'], None)
1247         self.assertEqual(action['args'], test_config)
cad4e3 1248
0d8ff5 1249     def test_add_directive_with_partial(self):
dd3cc8 1250         from tests import test_config
0c29cf 1251
0d8ff5 1252         config = self.config
WWI 1253         config.add_directive(
0c29cf 1254             'dummy_partial', 'tests.test_config.dummy_partial'
MM 1255         )
0d8ff5 1256         self.assertTrue(hasattr(config, 'dummy_partial'))
WWI 1257         config.dummy_partial()
1258         after = config.action_state
1259         action = after.actions[-1]
1260         self.assertEqual(action['discriminator'], 'partial')
1261         self.assertEqual(action['callable'], None)
1262         self.assertEqual(action['args'], test_config)
1263
1264     def test_add_directive_with_custom_callable(self):
dd3cc8 1265         from tests import test_config
0c29cf 1266
0d8ff5 1267         config = self.config
WWI 1268         config.add_directive(
0c29cf 1269             'dummy_callable', 'tests.test_config.dummy_callable'
MM 1270         )
0d8ff5 1271         self.assertTrue(hasattr(config, 'dummy_callable'))
WWI 1272         config.dummy_callable('discrim')
1273         after = config.action_state
1274         action = after.actions[-1]
1275         self.assertEqual(action['discriminator'], 'discrim')
1276         self.assertEqual(action['callable'], None)
1277         self.assertEqual(action['args'], test_config)
1278
cad4e3 1279     def test_extend_with_python_callable(self):
dd3cc8 1280         from tests import test_config
0c29cf 1281
cad4e3 1282         config = self.config
0c29cf 1283         config.add_directive('dummy_extend', dummy_extend)
fbd01a 1284         self.assertTrue(hasattr(config, 'dummy_extend'))
cad4e3 1285         config.dummy_extend('discrim')
b86fa9 1286         after = config.action_state
412b4a 1287         action = after.actions[-1]
CM 1288         self.assertEqual(action['discriminator'], 'discrim')
1289         self.assertEqual(action['callable'], None)
1290         self.assertEqual(action['args'], test_config)
cad4e3 1291
da358e 1292     def test_extend_same_name_doesnt_conflict(self):
cad4e3 1293         config = self.config
0c29cf 1294         config.add_directive('dummy_extend', dummy_extend)
MM 1295         config.add_directive('dummy_extend', dummy_extend2)
fbd01a 1296         self.assertTrue(hasattr(config, 'dummy_extend'))
da358e 1297         config.dummy_extend('discrim')
b86fa9 1298         after = config.action_state
412b4a 1299         action = after.actions[-1]
CM 1300         self.assertEqual(action['discriminator'], 'discrim')
1301         self.assertEqual(action['callable'], None)
1302         self.assertEqual(action['args'], config.registry)
cad4e3 1303
da358e 1304     def test_extend_action_method_successful(self):
2422ce 1305         config = self.config
0c29cf 1306         config.add_directive('dummy_extend', dummy_extend)
da358e 1307         config.dummy_extend('discrim')
CM 1308         config.dummy_extend('discrim')
1309         self.assertRaises(ConfigurationConflictError, config.commit)
035d03 1310
da358e 1311     def test_directive_persists_across_configurator_creations(self):
035d03 1312         config = self.config
da358e 1313         config.add_directive('dummy_extend', dummy_extend)
dd3cc8 1314         config2 = config.with_package('tests')
da358e 1315         config2.dummy_extend('discrim')
b86fa9 1316         after = config2.action_state
CM 1317         actions = after.actions
da358e 1318         self.assertEqual(len(actions), 1)
412b4a 1319         action = actions[0]
CM 1320         self.assertEqual(action['discriminator'], 'discrim')
1321         self.assertEqual(action['callable'], None)
1322         self.assertEqual(action['args'], config2.package)
2422ce 1323
0c29cf 1324
f9600f 1325 class TestConfigurator__add_predicate(unittest.TestCase):
CM 1326     def _makeOne(self):
1327         from pyramid.config import Configurator
0c29cf 1328
f9600f 1329         return Configurator()
CM 1330
1331     def test_factory_as_object(self):
1332         config = self._makeOne()
1333
0c29cf 1334         def _fakeAction(
MM 1335             discriminator,
1336             callable=None,
1337             args=(),
1338             kw=None,
1339             order=0,
1340             introspectables=(),
1341             **extra
1342         ):
f9600f 1343             self.assertEqual(len(introspectables), 1)
CM 1344             self.assertEqual(introspectables[0]['name'], 'testing')
1345             self.assertEqual(introspectables[0]['factory'], DummyPredicate)
1346
1347         config.action = _fakeAction
1348         config._add_predicate('route', 'testing', DummyPredicate)
1349
1350     def test_factory_as_dotted_name(self):
1351         config = self._makeOne()
1352
0c29cf 1353         def _fakeAction(
MM 1354             discriminator,
1355             callable=None,
1356             args=(),
1357             kw=None,
1358             order=0,
1359             introspectables=(),
1360             **extra
1361         ):
f9600f 1362             self.assertEqual(len(introspectables), 1)
CM 1363             self.assertEqual(introspectables[0]['name'], 'testing')
1364             self.assertEqual(introspectables[0]['factory'], DummyPredicate)
1365
1366         config.action = _fakeAction
1367         config._add_predicate(
0c29cf 1368             'route', 'testing', 'tests.test_config.test_init.DummyPredicate'
MM 1369         )
1370
1371
3d43f7 1372 class TestGlobalRegistriesIntegration(unittest.TestCase):
CM 1373     def setUp(self):
1374         from pyramid.config import global_registries
0c29cf 1375
3d43f7 1376         global_registries.empty()
CM 1377
1378     tearDown = setUp
1379
1380     def _makeConfigurator(self, *arg, **kw):
1381         from pyramid.config import Configurator
0c29cf 1382
3d43f7 1383         config = Configurator(*arg, **kw)
CM 1384         return config
1385
1386     def test_global_registries_empty(self):
1387         from pyramid.config import global_registries
0c29cf 1388
3d43f7 1389         self.assertEqual(global_registries.last, None)
CM 1390
1391     def test_global_registries(self):
1392         from pyramid.config import global_registries
0c29cf 1393
3d43f7 1394         config1 = self._makeConfigurator()
CM 1395         config1.make_wsgi_app()
1396         self.assertEqual(global_registries.last, config1.registry)
1397         config2 = self._makeConfigurator()
1398         config2.make_wsgi_app()
1399         self.assertEqual(global_registries.last, config2.registry)
0c29cf 1400         self.assertEqual(
MM 1401             list(global_registries), [config1.registry, config2.registry]
1402         )
3d43f7 1403         global_registries.remove(config2.registry)
CM 1404         self.assertEqual(global_registries.last, config1.registry)
0c29cf 1405
3d43f7 1406
427a02 1407 class DummyRequest:
CM 1408     subpath = ()
1409     matchdict = None
849196 1410     request_iface = IRequest
0c29cf 1411
f426e5 1412     def __init__(self, environ=None):
CM 1413         if environ is None:
1414             environ = {}
1415         self.environ = environ
427a02 1416         self.params = {}
CM 1417         self.cookies = {}
1418
0c29cf 1419
427a02 1420 class DummyThreadLocalManager(object):
804eb0 1421     def __init__(self):
MM 1422         self.pushed = {'registry': None, 'request': None}
1423         self.popped = False
0c29cf 1424
427a02 1425     def push(self, d):
CM 1426         self.pushed = d
0c29cf 1427
804eb0 1428     def get(self):
MM 1429         return self.pushed
0c29cf 1430
427a02 1431     def pop(self):
CM 1432         self.popped = True
1433
0c29cf 1434
d868ff 1435 class DummyRegistry(object):
a00621 1436     def __init__(self, adaptation=None, util=None):
d868ff 1437         self.utilities = []
CM 1438         self.adapters = []
1439         self.adaptation = adaptation
a00621 1440         self.util = util
0c29cf 1441
d868ff 1442     def subscribers(self, events, name):
CM 1443         self.events = events
1444         return events
0c29cf 1445
d868ff 1446     def registerUtility(self, *arg, **kw):
CM 1447         self.utilities.append((arg, kw))
0c29cf 1448
d868ff 1449     def registerAdapter(self, *arg, **kw):
CM 1450         self.adapters.append((arg, kw))
0c29cf 1451
d868ff 1452     def queryAdapter(self, *arg, **kw):
CM 1453         return self.adaptation
0c29cf 1454
a00621 1455     def queryUtility(self, *arg, **kw):
CM 1456         return self.util
0c29cf 1457
MM 1458
f9600f 1459 class DummyPredicate(object):
CM 1460     pass