Fixed #15561 -- Extended test setting override code added in r16165 with a decorator and a signal for setting changes.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16237 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
091c9b530e
commit
a3a53e0b73
|
@ -1,3 +1,5 @@
|
||||||
from django.dispatch import Signal
|
from django.dispatch import Signal
|
||||||
|
|
||||||
template_rendered = Signal(providing_args=["template", "context"])
|
template_rendered = Signal(providing_args=["template", "context"])
|
||||||
|
|
||||||
|
setting_changed = Signal(providing_args=["setting", "value"])
|
||||||
|
|
|
@ -2,7 +2,6 @@ from __future__ import with_statement
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from contextlib import contextmanager
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from urlparse import urlsplit, urlunsplit
|
from urlparse import urlsplit, urlunsplit
|
||||||
from xml.dom.minidom import parseString, Node
|
from xml.dom.minidom import parseString, Node
|
||||||
|
@ -17,7 +16,7 @@ from django.db import (transaction, connection, connections, DEFAULT_DB_ALIAS,
|
||||||
from django.http import QueryDict
|
from django.http import QueryDict
|
||||||
from django.test import _doctest as doctest
|
from django.test import _doctest as doctest
|
||||||
from django.test.client import Client
|
from django.test.client import Client
|
||||||
from django.test.utils import get_warnings_state, restore_warnings_state
|
from django.test.utils import get_warnings_state, restore_warnings_state, override_settings
|
||||||
from django.utils import simplejson, unittest as ut2
|
from django.utils import simplejson, unittest as ut2
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
|
|
||||||
|
@ -342,21 +341,12 @@ class TransactionTestCase(ut2.TestCase):
|
||||||
"""
|
"""
|
||||||
restore_warnings_state(self._warnings_state)
|
restore_warnings_state(self._warnings_state)
|
||||||
|
|
||||||
@contextmanager
|
def settings(self, **kwargs):
|
||||||
def settings(self, **options):
|
|
||||||
"""
|
"""
|
||||||
A context manager that temporarily sets a setting and reverts
|
A context manager that temporarily sets a setting and reverts
|
||||||
back to the original value when exiting the context.
|
back to the original value when exiting the context.
|
||||||
"""
|
"""
|
||||||
old_wrapped = settings._wrapped
|
return override_settings(**kwargs)
|
||||||
override = UserSettingsHolder(settings._wrapped)
|
|
||||||
try:
|
|
||||||
for key, new_value in options.items():
|
|
||||||
setattr(override, key, new_value)
|
|
||||||
settings._wrapped = override
|
|
||||||
yield
|
|
||||||
finally:
|
|
||||||
settings._wrapped = old_wrapped
|
|
||||||
|
|
||||||
def assertRedirects(self, response, expected_url, status_code=302,
|
def assertRedirects(self, response, expected_url, status_code=302,
|
||||||
target_status_code=200, host=None, msg_prefix=''):
|
target_status_code=200, host=None, msg_prefix=''):
|
||||||
|
|
|
@ -1,17 +1,23 @@
|
||||||
|
from __future__ import with_statement
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
import warnings
|
import warnings
|
||||||
from django.conf import settings
|
from django.conf import settings, UserSettingsHolder
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.mail.backends import locmem
|
from django.core.mail.backends import locmem
|
||||||
from django.test import signals
|
from django.test.signals import template_rendered, setting_changed
|
||||||
from django.template import Template, loader, TemplateDoesNotExist
|
from django.template import Template, loader, TemplateDoesNotExist
|
||||||
from django.template.loaders import cached
|
from django.template.loaders import cached
|
||||||
from django.utils.translation import deactivate
|
from django.utils.translation import deactivate
|
||||||
|
from django.utils.functional import wraps
|
||||||
|
|
||||||
__all__ = ('Approximate', 'ContextList', 'setup_test_environment',
|
|
||||||
'teardown_test_environment', 'get_runner')
|
__all__ = (
|
||||||
|
'Approximate', 'ContextList', 'get_runner', 'override_settings',
|
||||||
|
'setup_test_environment', 'teardown_test_environment',
|
||||||
|
)
|
||||||
|
|
||||||
RESTORE_LOADERS_ATTR = '_original_template_source_loaders'
|
RESTORE_LOADERS_ATTR = '_original_template_source_loaders'
|
||||||
|
|
||||||
|
@ -56,7 +62,7 @@ def instrumented_test_render(self, context):
|
||||||
An instrumented Template render method, providing a signal
|
An instrumented Template render method, providing a signal
|
||||||
that can be intercepted by the test system Client
|
that can be intercepted by the test system Client
|
||||||
"""
|
"""
|
||||||
signals.template_rendered.send(sender=self, template=self, context=context)
|
template_rendered.send(sender=self, template=self, context=context)
|
||||||
return self.nodelist.render(context)
|
return self.nodelist.render(context)
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,3 +166,46 @@ def restore_template_loaders():
|
||||||
"""
|
"""
|
||||||
loader.template_source_loaders = getattr(loader, RESTORE_LOADERS_ATTR)
|
loader.template_source_loaders = getattr(loader, RESTORE_LOADERS_ATTR)
|
||||||
delattr(loader, RESTORE_LOADERS_ATTR)
|
delattr(loader, RESTORE_LOADERS_ATTR)
|
||||||
|
|
||||||
|
|
||||||
|
class OverrideSettingsHolder(UserSettingsHolder):
|
||||||
|
"""
|
||||||
|
A custom setting holder that sends a signal upon change.
|
||||||
|
"""
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
UserSettingsHolder.__setattr__(self, name, value)
|
||||||
|
setting_changed.send(sender=name, setting=name, value=value)
|
||||||
|
|
||||||
|
|
||||||
|
class override_settings(object):
|
||||||
|
"""
|
||||||
|
Acts as either a decorator, or a context manager. If it's a decorator it
|
||||||
|
takes a function and returns a wrapped function. If it's a contextmanager
|
||||||
|
it's used with the ``with`` statement. In either event entering/exiting
|
||||||
|
are called before and after, respectively, the function/block is executed.
|
||||||
|
"""
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.options = kwargs
|
||||||
|
self.wrapped = settings._wrapped
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self.enable()
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
|
self.disable()
|
||||||
|
|
||||||
|
def __call__(self, func):
|
||||||
|
@wraps(func)
|
||||||
|
def inner(*args, **kwargs):
|
||||||
|
with self:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
return inner
|
||||||
|
|
||||||
|
def enable(self):
|
||||||
|
override = OverrideSettingsHolder(settings._wrapped)
|
||||||
|
for key, new_value in self.options.items():
|
||||||
|
setattr(override, key, new_value)
|
||||||
|
settings._wrapped = override
|
||||||
|
|
||||||
|
def disable(self):
|
||||||
|
settings._wrapped = self.wrapped
|
||||||
|
|
|
@ -460,6 +460,29 @@ Test signals
|
||||||
|
|
||||||
Signals only sent when :doc:`running tests </topics/testing>`.
|
Signals only sent when :doc:`running tests </topics/testing>`.
|
||||||
|
|
||||||
|
setting_changed
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
|
.. data:: django.test.signals.setting_changed
|
||||||
|
:module:
|
||||||
|
|
||||||
|
Sent when some :ref:`settings are overridden <overriding-setting>` with the
|
||||||
|
:meth:`django.test.TestCase.setting` context manager or the
|
||||||
|
:func:`django.test.utils.override_settings` decorator/context manager.
|
||||||
|
|
||||||
|
Arguments sent with this signal:
|
||||||
|
|
||||||
|
``sender``
|
||||||
|
The setting name (string).
|
||||||
|
|
||||||
|
``setting``
|
||||||
|
Same as sender
|
||||||
|
|
||||||
|
``value``
|
||||||
|
The new setting value.
|
||||||
|
|
||||||
template_rendered
|
template_rendered
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
|
@ -1361,6 +1361,8 @@ For example::
|
||||||
This test case will flush *all* the test databases before running
|
This test case will flush *all* the test databases before running
|
||||||
``testIndexPageView``.
|
``testIndexPageView``.
|
||||||
|
|
||||||
|
.. _overriding-setting:
|
||||||
|
|
||||||
Overriding settings
|
Overriding settings
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -1376,7 +1378,14 @@ this use case Django provides a standard `Python context manager`_
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
class LoginTestCase(TestCase):
|
class LoginTestCase(TestCase):
|
||||||
def test_overriding_settings(self):
|
|
||||||
|
def test_login(self):
|
||||||
|
|
||||||
|
# First check for the default behavior
|
||||||
|
response = self.client.get('/sekrit/')
|
||||||
|
self.assertRedirects(response, '/accounts/login/?next=/sekrit/')
|
||||||
|
|
||||||
|
# Then override the LOGING_URL setting
|
||||||
with self.settings(LOGIN_URL='/other/login/'):
|
with self.settings(LOGIN_URL='/other/login/'):
|
||||||
response = self.client.get('/sekrit/')
|
response = self.client.get('/sekrit/')
|
||||||
self.assertRedirects(response, '/other/login/?next=/sekrit/')
|
self.assertRedirects(response, '/other/login/?next=/sekrit/')
|
||||||
|
@ -1384,7 +1393,58 @@ this use case Django provides a standard `Python context manager`_
|
||||||
This example will override the :setting:`LOGIN_URL` setting for the code
|
This example will override the :setting:`LOGIN_URL` setting for the code
|
||||||
in the ``with`` block and reset its value to the previous state afterwards.
|
in the ``with`` block and reset its value to the previous state afterwards.
|
||||||
|
|
||||||
|
.. function:: utils.override_settings
|
||||||
|
|
||||||
|
In case you want to override a setting for just one test method or even the
|
||||||
|
whole TestCase class, Django provides the
|
||||||
|
:func:`django.test.utils.override_settings` decorator_. It's used like this::
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.test.utils import override_settings
|
||||||
|
|
||||||
|
class LoginTestCase(TestCase):
|
||||||
|
|
||||||
|
@override_settings(LOGIN_URL='/other/login/')
|
||||||
|
def test_login(self):
|
||||||
|
response = self.client.get('/sekrit/')
|
||||||
|
self.assertRedirects(response, '/other/login/?next=/sekrit/')
|
||||||
|
|
||||||
|
The decorator can also be applied to test case classes::
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.test.utils import override_settings
|
||||||
|
|
||||||
|
class LoginTestCase(TestCase):
|
||||||
|
|
||||||
|
def test_login(self):
|
||||||
|
response = self.client.get('/sekrit/')
|
||||||
|
self.assertRedirects(response, '/other/login/?next=/sekrit/')
|
||||||
|
|
||||||
|
LoginTestCase = override_settings(LOGIN_URL='/other/login/')(LoginTestCase)
|
||||||
|
|
||||||
|
On Python 2.6 and higher you can also use the well known decorator syntax to
|
||||||
|
decorate the class::
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.test.utils import override_settings
|
||||||
|
|
||||||
|
@override_settings(LOGIN_URL='/other/login/')
|
||||||
|
class LoginTestCase(TestCase):
|
||||||
|
|
||||||
|
def test_login(self):
|
||||||
|
response = self.client.get('/sekrit/')
|
||||||
|
self.assertRedirects(response, '/other/login/?next=/sekrit/')
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
When overriding settings make sure to also handle the cases in which
|
||||||
|
Django or your app's code use a cache or another feature that retain
|
||||||
|
state even if the setting is changed. Django provides the
|
||||||
|
:data:`django.test.signals.setting_changed` signal to connect cleanup
|
||||||
|
and other state resetting callbacks to.
|
||||||
|
|
||||||
.. _`Python context manager`: http://www.python.org/dev/peps/pep-0343/
|
.. _`Python context manager`: http://www.python.org/dev/peps/pep-0343/
|
||||||
|
.. _`decorator`: http://www.python.org/dev/peps/pep-0318/
|
||||||
|
|
||||||
Emptying the test outbox
|
Emptying the test outbox
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -9,48 +9,14 @@ from StringIO import StringIO
|
||||||
import tempfile
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.mail import (EmailMessage, mail_admins, mail_managers,
|
from django.core.mail import (EmailMessage, mail_admins, mail_managers,
|
||||||
EmailMultiAlternatives, send_mail, send_mass_mail)
|
EmailMultiAlternatives, send_mail, send_mass_mail)
|
||||||
from django.core.mail.backends import console, dummy, locmem, filebased, smtp
|
from django.core.mail.backends import console, dummy, locmem, filebased, smtp
|
||||||
from django.core.mail.message import BadHeaderError
|
from django.core.mail.message import BadHeaderError
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from django.test.utils import override_settings
|
||||||
from django.utils.translation import ugettext_lazy
|
from django.utils.translation import ugettext_lazy
|
||||||
from django.utils.functional import wraps
|
|
||||||
|
|
||||||
|
|
||||||
def alter_django_settings(**kwargs):
|
|
||||||
oldvalues = {}
|
|
||||||
nonexistant = []
|
|
||||||
for setting, newvalue in kwargs.iteritems():
|
|
||||||
try:
|
|
||||||
oldvalues[setting] = getattr(settings, setting)
|
|
||||||
except AttributeError:
|
|
||||||
nonexistant.append(setting)
|
|
||||||
setattr(settings, setting, newvalue)
|
|
||||||
return oldvalues, nonexistant
|
|
||||||
|
|
||||||
|
|
||||||
def restore_django_settings(state):
|
|
||||||
oldvalues, nonexistant = state
|
|
||||||
for setting, oldvalue in oldvalues.iteritems():
|
|
||||||
setattr(settings, setting, oldvalue)
|
|
||||||
for setting in nonexistant:
|
|
||||||
delattr(settings, setting)
|
|
||||||
|
|
||||||
|
|
||||||
def with_django_settings(**kwargs):
|
|
||||||
def decorator(test):
|
|
||||||
@wraps(test)
|
|
||||||
def decorated_test(self):
|
|
||||||
state = alter_django_settings(**kwargs)
|
|
||||||
try:
|
|
||||||
return test(self)
|
|
||||||
finally:
|
|
||||||
restore_django_settings(state)
|
|
||||||
return decorated_test
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
class MailTests(TestCase):
|
class MailTests(TestCase):
|
||||||
|
@ -251,7 +217,7 @@ class MailTests(TestCase):
|
||||||
shutil.rmtree(tmp_dir)
|
shutil.rmtree(tmp_dir)
|
||||||
self.assertTrue(isinstance(mail.get_connection(), locmem.EmailBackend))
|
self.assertTrue(isinstance(mail.get_connection(), locmem.EmailBackend))
|
||||||
|
|
||||||
@with_django_settings(
|
@override_settings(
|
||||||
EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend',
|
EMAIL_BACKEND='django.core.mail.backends.locmem.EmailBackend',
|
||||||
ADMINS=[('nobody', 'nobody@example.com')],
|
ADMINS=[('nobody', 'nobody@example.com')],
|
||||||
MANAGERS=[('nobody', 'nobody@example.com')])
|
MANAGERS=[('nobody', 'nobody@example.com')])
|
||||||
|
@ -323,10 +289,11 @@ class BaseEmailBackendTests(object):
|
||||||
email_backend = None
|
email_backend = None
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.__settings_state = alter_django_settings(EMAIL_BACKEND=self.email_backend)
|
self.settings_override = override_settings(EMAIL_BACKEND=self.email_backend)
|
||||||
|
self.settings_override.enable()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
restore_django_settings(self.__settings_state)
|
self.settings_override.disable()
|
||||||
|
|
||||||
def assertStartsWith(self, first, second):
|
def assertStartsWith(self, first, second):
|
||||||
if not first.startswith(second):
|
if not first.startswith(second):
|
||||||
|
@ -375,7 +342,7 @@ class BaseEmailBackendTests(object):
|
||||||
self.assertEqual(message.get_payload(), "Content")
|
self.assertEqual(message.get_payload(), "Content")
|
||||||
self.assertEqual(message["from"], "=?utf-8?q?Firstname_S=C3=BCrname?= <from@example.com>")
|
self.assertEqual(message["from"], "=?utf-8?q?Firstname_S=C3=BCrname?= <from@example.com>")
|
||||||
|
|
||||||
@with_django_settings(MANAGERS=[('nobody', 'nobody@example.com')])
|
@override_settings(MANAGERS=[('nobody', 'nobody@example.com')])
|
||||||
def test_html_mail_managers(self):
|
def test_html_mail_managers(self):
|
||||||
"""Test html_message argument to mail_managers"""
|
"""Test html_message argument to mail_managers"""
|
||||||
mail_managers('Subject', 'Content', html_message='HTML Content')
|
mail_managers('Subject', 'Content', html_message='HTML Content')
|
||||||
|
@ -390,7 +357,7 @@ class BaseEmailBackendTests(object):
|
||||||
self.assertEqual(message.get_payload(1).get_payload(), 'HTML Content')
|
self.assertEqual(message.get_payload(1).get_payload(), 'HTML Content')
|
||||||
self.assertEqual(message.get_payload(1).get_content_type(), 'text/html')
|
self.assertEqual(message.get_payload(1).get_content_type(), 'text/html')
|
||||||
|
|
||||||
@with_django_settings(ADMINS=[('nobody', 'nobody@example.com')])
|
@override_settings(ADMINS=[('nobody', 'nobody@example.com')])
|
||||||
def test_html_mail_admins(self):
|
def test_html_mail_admins(self):
|
||||||
"""Test html_message argument to mail_admins """
|
"""Test html_message argument to mail_admins """
|
||||||
mail_admins('Subject', 'Content', html_message='HTML Content')
|
mail_admins('Subject', 'Content', html_message='HTML Content')
|
||||||
|
@ -405,8 +372,9 @@ class BaseEmailBackendTests(object):
|
||||||
self.assertEqual(message.get_payload(1).get_payload(), 'HTML Content')
|
self.assertEqual(message.get_payload(1).get_payload(), 'HTML Content')
|
||||||
self.assertEqual(message.get_payload(1).get_content_type(), 'text/html')
|
self.assertEqual(message.get_payload(1).get_content_type(), 'text/html')
|
||||||
|
|
||||||
@with_django_settings(ADMINS=[('nobody', 'nobody+admin@example.com')],
|
@override_settings(
|
||||||
MANAGERS=[('nobody', 'nobody+manager@example.com')])
|
ADMINS=[('nobody', 'nobody+admin@example.com')],
|
||||||
|
MANAGERS=[('nobody', 'nobody+manager@example.com')])
|
||||||
def test_manager_and_admin_mail_prefix(self):
|
def test_manager_and_admin_mail_prefix(self):
|
||||||
"""
|
"""
|
||||||
String prefix + lazy translated subject = bad output
|
String prefix + lazy translated subject = bad output
|
||||||
|
@ -421,7 +389,7 @@ class BaseEmailBackendTests(object):
|
||||||
message = self.get_the_message()
|
message = self.get_the_message()
|
||||||
self.assertEqual(message.get('subject'), '[Django] Subject')
|
self.assertEqual(message.get('subject'), '[Django] Subject')
|
||||||
|
|
||||||
@with_django_settings(ADMINS=(), MANAGERS=())
|
@override_settings(ADMINS=(), MANAGERS=())
|
||||||
def test_empty_admins(self):
|
def test_empty_admins(self):
|
||||||
"""
|
"""
|
||||||
Test that mail_admins/mail_managers doesn't connect to the mail server
|
Test that mail_admins/mail_managers doesn't connect to the mail server
|
||||||
|
@ -501,13 +469,14 @@ class FileBackendTests(BaseEmailBackendTests, TestCase):
|
||||||
email_backend = 'django.core.mail.backends.filebased.EmailBackend'
|
email_backend = 'django.core.mail.backends.filebased.EmailBackend'
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(FileBackendTests, self).setUp()
|
|
||||||
self.tmp_dir = tempfile.mkdtemp()
|
self.tmp_dir = tempfile.mkdtemp()
|
||||||
self.__settings_state = alter_django_settings(EMAIL_FILE_PATH=self.tmp_dir)
|
self.addCleanup(shutil.rmtree, self.tmp_dir)
|
||||||
|
self.settings_override = override_settings(EMAIL_FILE_PATH=self.tmp_dir)
|
||||||
|
self.settings_override.enable()
|
||||||
|
super(FileBackendTests, self).setUp()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
restore_django_settings(self.__settings_state)
|
self.settings_override.disable()
|
||||||
shutil.rmtree(self.tmp_dir)
|
|
||||||
super(FileBackendTests, self).tearDown()
|
super(FileBackendTests, self).tearDown()
|
||||||
|
|
||||||
def flush_mailbox(self):
|
def flush_mailbox(self):
|
||||||
|
@ -642,13 +611,15 @@ class SMTPBackendTests(BaseEmailBackendTests, TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
cls.server = FakeSMTPServer(('127.0.0.1', 0), None)
|
cls.server = FakeSMTPServer(('127.0.0.1', 0), None)
|
||||||
cls.settings = alter_django_settings(
|
cls.settings_override = override_settings(
|
||||||
EMAIL_HOST="127.0.0.1",
|
EMAIL_HOST="127.0.0.1",
|
||||||
EMAIL_PORT=cls.server.socket.getsockname()[1])
|
EMAIL_PORT=cls.server.socket.getsockname()[1])
|
||||||
|
cls.settings_override.enable()
|
||||||
cls.server.start()
|
cls.server.start()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
|
cls.settings_override.disable()
|
||||||
cls.server.stop()
|
cls.server.stop()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
|
@ -1,7 +1,22 @@
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement
|
||||||
import os
|
import os, sys
|
||||||
from django.conf import settings, global_settings
|
from django.conf import settings, global_settings
|
||||||
from django.test import TestCase
|
from django.test import TestCase, signals
|
||||||
|
from django.test.utils import override_settings
|
||||||
|
from django.utils.unittest import skipIf
|
||||||
|
|
||||||
|
|
||||||
|
class SettingGetter(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.test = getattr(settings, 'TEST', 'undefined')
|
||||||
|
|
||||||
|
testvalue = None
|
||||||
|
|
||||||
|
def signal_callback(sender, setting, value, **kwargs):
|
||||||
|
global testvalue
|
||||||
|
testvalue = value
|
||||||
|
|
||||||
|
signals.setting_changed.connect(signal_callback, sender='TEST')
|
||||||
|
|
||||||
class SettingsTests(TestCase):
|
class SettingsTests(TestCase):
|
||||||
|
|
||||||
|
@ -29,6 +44,43 @@ class SettingsTests(TestCase):
|
||||||
settings.TEST = 'test'
|
settings.TEST = 'test'
|
||||||
self.assertRaises(AttributeError, getattr, settings, 'TEST')
|
self.assertRaises(AttributeError, getattr, settings, 'TEST')
|
||||||
|
|
||||||
|
@override_settings(TEST='override')
|
||||||
|
def test_decorator(self):
|
||||||
|
self.assertEqual('override', settings.TEST)
|
||||||
|
|
||||||
|
def test_context_manager(self):
|
||||||
|
self.assertRaises(AttributeError, getattr, settings, 'TEST')
|
||||||
|
override = override_settings(TEST='override')
|
||||||
|
self.assertRaises(AttributeError, getattr, settings, 'TEST')
|
||||||
|
override.enable()
|
||||||
|
self.assertEqual('override', settings.TEST)
|
||||||
|
override.disable()
|
||||||
|
self.assertRaises(AttributeError, getattr, settings, 'TEST')
|
||||||
|
|
||||||
|
def test_class_decorator(self):
|
||||||
|
self.assertEqual(SettingGetter().test, 'undefined')
|
||||||
|
DecoratedSettingGetter = override_settings(TEST='override')(SettingGetter)
|
||||||
|
self.assertEqual(DecoratedSettingGetter().test, 'override')
|
||||||
|
self.assertRaises(AttributeError, getattr, settings, 'TEST')
|
||||||
|
|
||||||
|
@skipIf(sys.version_info[:2] < (2, 6), "Python version is lower than 2.6")
|
||||||
|
def test_new_class_decorator(self):
|
||||||
|
self.assertEqual(SettingGetter().test, 'undefined')
|
||||||
|
@override_settings(TEST='override')
|
||||||
|
class DecoratedSettingGetter(SettingGetter):
|
||||||
|
pass
|
||||||
|
self.assertEqual(DecoratedSettingGetter().test, 'override')
|
||||||
|
self.assertRaises(AttributeError, getattr, settings, 'TEST')
|
||||||
|
|
||||||
|
def test_signal_callback_context_manager(self):
|
||||||
|
self.assertRaises(AttributeError, getattr, settings, 'TEST')
|
||||||
|
with self.settings(TEST='override'):
|
||||||
|
self.assertEqual(testvalue, 'override')
|
||||||
|
|
||||||
|
@override_settings(TEST='override')
|
||||||
|
def test_signal_callback_decorator(self):
|
||||||
|
self.assertEqual(testvalue, 'override')
|
||||||
|
|
||||||
#
|
#
|
||||||
# Regression tests for #10130: deleting settings.
|
# Regression tests for #10130: deleting settings.
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue