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