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