Dropped AppCache._empty, _with_app and _without_app.

It's now easier to achieve the same effect with modify_settings or
override_settings.
This commit is contained in:
Aymeric Augustin 2013-12-23 10:37:34 +01:00
parent 5241763c81
commit da16bb30ff
21 changed files with 121 additions and 228 deletions

View File

@ -1,7 +1,6 @@
"Utilities for loading models and the modules that contain them." "Utilities for loading models and the modules that contain them."
from collections import defaultdict, OrderedDict from collections import defaultdict, OrderedDict
from contextlib import contextmanager
import os import os
import sys import sys
import warnings import warnings
@ -350,61 +349,6 @@ class AppCache(object):
""" """
self.app_configs = self.stored_app_configs.pop() self.app_configs = self.stored_app_configs.pop()
### DANGEROUS METHODS ### (only used to preserve existing tests)
def _begin_with_app(self, app_name):
# Returns an opaque value that can be passed to _end_with_app().
app_config = AppConfig.create(app_name)
if app_config.label in self.app_configs:
return None
else:
app_config.import_models(self.all_models[app_config.label])
self.app_configs[app_config.label] = app_config
return app_config
def _end_with_app(self, app_config):
if app_config is not None:
del self.app_configs[app_config.label]
@contextmanager
def _with_app(self, app_name):
app_config = self._begin_with_app(app_name)
try:
yield
finally:
self._end_with_app(app_config)
def _begin_without_app(self, app_name):
# Returns an opaque value that can be passed to _end_without_app().
return self.app_configs.pop(app_name.rpartition(".")[2], None)
def _end_without_app(self, app_config):
if app_config is not None:
self.app_configs[app_config.label] = app_config
@contextmanager
def _without_app(self, app_name):
app_config = self._begin_without_app(app_name)
try:
yield
finally:
self._end_without_app(app_config)
def _begin_empty(self):
app_configs, self.app_configs = self.app_configs, OrderedDict()
return app_configs
def _end_empty(self, app_configs):
self.app_configs = app_configs
@contextmanager
def _empty(self):
app_configs = self._begin_empty()
try:
yield
finally:
self._end_empty(app_configs)
### DEPRECATED METHODS GO BELOW THIS LINE ### ### DEPRECATED METHODS GO BELOW THIS LINE ###
def load_app(self, app_name): def load_app(self, app_name):

View File

@ -1,6 +1,5 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.apps import app_cache
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.views import shortcut from django.contrib.contenttypes.views import shortcut
from django.contrib.sites.models import get_current_site from django.contrib.sites.models import get_current_site
@ -222,12 +221,12 @@ class ContentTypesTests(TestCase):
user_ct = ContentType.objects.get_for_model(FooWithUrl) user_ct = ContentType.objects.get_for_model(FooWithUrl)
obj = FooWithUrl.objects.create(name="john") obj = FooWithUrl.objects.create(name="john")
with app_cache._with_app('django.contrib.sites'): with self.modify_settings(INSTALLED_APPS={'append': 'django.contrib.sites'}):
response = shortcut(request, user_ct.id, obj.id) response = shortcut(request, user_ct.id, obj.id)
self.assertEqual("http://%s/users/john/" % get_current_site(request).domain, self.assertEqual("http://%s/users/john/" % get_current_site(request).domain,
response._headers.get("location")[1]) response._headers.get("location")[1])
with app_cache._without_app('django.contrib.sites'): with self.modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'}):
response = shortcut(request, user_ct.id, obj.id) response = shortcut(request, user_ct.id, obj.id)
self.assertEqual("http://Example.com/users/john/", self.assertEqual("http://Example.com/users/john/",
response._headers.get("location")[1]) response._headers.get("location")[1])

View File

@ -3,17 +3,17 @@ from __future__ import unicode_literals
from unittest import skipUnless from unittest import skipUnless
from xml.dom import minidom from xml.dom import minidom
from django.apps import app_cache
from django.conf import settings from django.conf import settings
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.contrib.gis.geos import HAS_GEOS from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
from django.test import TestCase from django.test import TestCase, modify_settings
if HAS_GEOS: if HAS_GEOS:
from .models import City from .models import City
@modify_settings(INSTALLED_APPS={'append': 'django.contrib.sites'})
@skipUnless(HAS_GEOS and HAS_SPATIAL_DB, "Geos and spatial db are required.") @skipUnless(HAS_GEOS and HAS_SPATIAL_DB, "Geos and spatial db are required.")
class GeoFeedTest(TestCase): class GeoFeedTest(TestCase):
@ -21,10 +21,6 @@ class GeoFeedTest(TestCase):
def setUp(self): def setUp(self):
Site(id=settings.SITE_ID, domain="example.com", name="example.com").save() Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
self._with_sites = app_cache._begin_with_app('django.contrib.sites')
def tearDown(self):
app_cache._end_with_app(self._with_sites)
def assertChildNodes(self, elem, expected): def assertChildNodes(self, elem, expected):
"Taken from syndication/tests.py." "Taken from syndication/tests.py."

View File

@ -6,12 +6,11 @@ from xml.dom import minidom
import os import os
import zipfile import zipfile
from django.apps import app_cache
from django.conf import settings from django.conf import settings
from django.contrib.gis.geos import HAS_GEOS from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.tests.utils import HAS_SPATIAL_DB from django.contrib.gis.tests.utils import HAS_SPATIAL_DB
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.test import TestCase from django.test import TestCase, modify_settings
from django.test.utils import IgnoreDeprecationWarningsMixin from django.test.utils import IgnoreDeprecationWarningsMixin
from django.utils._os import upath from django.utils._os import upath
@ -19,6 +18,7 @@ if HAS_GEOS:
from .models import City, Country from .models import City, Country
@modify_settings(INSTALLED_APPS={'append': 'django.contrib.sites'})
@skipUnless(HAS_GEOS and HAS_SPATIAL_DB, "Geos and spatial db are required.") @skipUnless(HAS_GEOS and HAS_SPATIAL_DB, "Geos and spatial db are required.")
class GeoSitemapTest(IgnoreDeprecationWarningsMixin, TestCase): class GeoSitemapTest(IgnoreDeprecationWarningsMixin, TestCase):
@ -27,11 +27,6 @@ class GeoSitemapTest(IgnoreDeprecationWarningsMixin, TestCase):
def setUp(self): def setUp(self):
super(GeoSitemapTest, self).setUp() super(GeoSitemapTest, self).setUp()
Site(id=settings.SITE_ID, domain="example.com", name="example.com").save() Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
self._with_sites = app_cache._begin_with_app('django.contrib.sites')
def tearDown(self):
app_cache._end_with_app(self._with_sites)
super(GeoSitemapTest, self).tearDown()
def assertChildNodes(self, elem, expected): def assertChildNodes(self, elem, expected):
"Taken from syndication/tests.py." "Taken from syndication/tests.py."

View File

@ -2,14 +2,14 @@ from unittest import skipUnless
from django import http from django import http
from django.apps import app_cache from django.apps import app_cache
from django.conf import settings, global_settings from django.conf import global_settings
from django.contrib.messages import constants, utils, get_level, set_level from django.contrib.messages import constants, utils, get_level, set_level
from django.contrib.messages.api import MessageFailure from django.contrib.messages.api import MessageFailure
from django.contrib.messages.constants import DEFAULT_LEVELS from django.contrib.messages.constants import DEFAULT_LEVELS
from django.contrib.messages.storage import default_storage, base from django.contrib.messages.storage import default_storage, base
from django.contrib.messages.storage.base import Message from django.contrib.messages.storage.base import Message
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test.utils import override_settings from django.test.utils import modify_settings, override_settings
from django.utils.translation import ugettext_lazy from django.utils.translation import ugettext_lazy
@ -219,20 +219,17 @@ class BaseTests(object):
for msg in data['messages']: for msg in data['messages']:
self.assertContains(response, msg) self.assertContains(response, msg)
@override_settings( @modify_settings(
MIDDLEWARE_CLASSES=filter( INSTALLED_APPS={'remove': 'django.contrib.messages'},
lambda m: 'MessageMiddleware' not in m, settings.MIDDLEWARE_CLASSES), MIDDLEWARE_CLASSES={'remove': 'django.contrib.messages.middleware.MessageMiddleware'},
TEMPLATE_CONTEXT_PROCESSORS=filter( TEMPLATE_CONTEXT_PROCESSORS={'remove': 'django.contrib.messages.context_processors.messages'},
lambda p: 'context_processors.messages' not in p,
settings.TEMPLATE_CONTEXT_PROCESSORS),
MESSAGE_LEVEL=constants.DEBUG
) )
@override_settings(MESSAGE_LEVEL=constants.DEBUG)
def test_middleware_disabled(self): def test_middleware_disabled(self):
""" """
Tests that, when the middleware is disabled, an exception is raised Tests that, when the middleware is disabled, an exception is raised
when one attempts to store a message. when one attempts to store a message.
""" """
with app_cache._without_app('django.contrib.messages'):
data = { data = {
'messages': ['Test message %d' % x for x in range(5)], 'messages': ['Test message %d' % x for x in range(5)],
} }
@ -243,20 +240,16 @@ class BaseTests(object):
self.assertRaises(MessageFailure, self.client.post, add_url, self.assertRaises(MessageFailure, self.client.post, add_url,
data, follow=True) data, follow=True)
@override_settings( @modify_settings(
MIDDLEWARE_CLASSES=filter( INSTALLED_APPS={'remove': 'django.contrib.messages'},
lambda m: 'MessageMiddleware' not in m, settings.MIDDLEWARE_CLASSES), MIDDLEWARE_CLASSES={'remove': 'django.contrib.messages.middleware.MessageMiddleware'},
TEMPLATE_CONTEXT_PROCESSORS=filter( TEMPLATE_CONTEXT_PROCESSORS={'remove': 'django.contrib.messages.context_processors.messages'},
lambda p: 'context_processors.messages' not in p,
settings.TEMPLATE_CONTEXT_PROCESSORS),
MESSAGE_LEVEL=constants.DEBUG
) )
def test_middleware_disabled_fail_silently(self): def test_middleware_disabled_fail_silently(self):
""" """
Tests that, when the middleware is disabled, an exception is not Tests that, when the middleware is disabled, an exception is not
raised if 'fail_silently' = True raised if 'fail_silently' = True
""" """
with app_cache._without_app('django.contrib.messages'):
data = { data = {
'messages': ['Test message %d' % x for x in range(5)], 'messages': ['Test message %d' % x for x in range(5)],
'fail_silently': True, 'fail_silently': True,

View File

@ -1,22 +1,18 @@
from django import http from django import http
from django.apps import app_cache
from django.conf import settings from django.conf import settings
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings from django.test.utils import modify_settings, override_settings
from django.utils import six from django.utils import six
from .middleware import RedirectFallbackMiddleware from .middleware import RedirectFallbackMiddleware
from .models import Redirect from .models import Redirect
@override_settings( @modify_settings(MIDDLEWARE_CLASSES={'append':
APPEND_SLASH=False, 'django.contrib.redirects.middleware.RedirectFallbackMiddleware'})
MIDDLEWARE_CLASSES=list(settings.MIDDLEWARE_CLASSES) + @override_settings(APPEND_SLASH=False, SITE_ID=1)
['django.contrib.redirects.middleware.RedirectFallbackMiddleware'],
SITE_ID=1,
)
class RedirectTests(TestCase): class RedirectTests(TestCase):
def setUp(self): def setUp(self):
@ -57,8 +53,8 @@ class RedirectTests(TestCase):
response = self.client.get('/initial') response = self.client.get('/initial')
self.assertEqual(response.status_code, 410) self.assertEqual(response.status_code, 410)
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
def test_sites_not_installed(self): def test_sites_not_installed(self):
with app_cache._without_app('django.contrib.sites'):
with self.assertRaises(ImproperlyConfigured): with self.assertRaises(ImproperlyConfigured):
RedirectFallbackMiddleware() RedirectFallbackMiddleware()
@ -69,11 +65,9 @@ class OverriddenRedirectFallbackMiddleware(RedirectFallbackMiddleware):
response_redirect_class = http.HttpResponseRedirect response_redirect_class = http.HttpResponseRedirect
@override_settings( @modify_settings(MIDDLEWARE_CLASSES={'append':
MIDDLEWARE_CLASSES=list(settings.MIDDLEWARE_CLASSES) + 'django.contrib.redirects.tests.OverriddenRedirectFallbackMiddleware'})
['django.contrib.redirects.tests.OverriddenRedirectFallbackMiddleware'], @override_settings(SITE_ID=1)
SITE_ID=1,
)
class OverriddenRedirectMiddlewareTests(TestCase): class OverriddenRedirectMiddlewareTests(TestCase):
def setUp(self): def setUp(self):

View File

@ -9,7 +9,7 @@ from django.conf import settings
from django.contrib.sitemaps import Sitemap, GenericSitemap from django.contrib.sitemaps import Sitemap, GenericSitemap
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.test.utils import override_settings from django.test import modify_settings, override_settings
from django.utils.formats import localize from django.utils.formats import localize
from django.utils._os import upath from django.utils._os import upath
from django.utils.translation import activate, deactivate from django.utils.translation import activate, deactivate
@ -106,10 +106,10 @@ class HTTPSitemapTests(SitemapTestsBase):
self.assertContains(response, '<lastmod>%s</lastmod>' % date.today()) self.assertContains(response, '<lastmod>%s</lastmod>' % date.today())
deactivate() deactivate()
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
def test_requestsite_sitemap(self): def test_requestsite_sitemap(self):
# Make sure hitting the flatpages sitemap without the sites framework # Make sure hitting the flatpages sitemap without the sites framework
# installed doesn't raise an exception. # installed doesn't raise an exception.
with app_cache._without_app('django.contrib.sites'):
response = self.client.get('/simple/sitemap.xml') response = self.client.get('/simple/sitemap.xml')
expected_content = """<?xml version="1.0" encoding="UTF-8"?> expected_content = """<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@ -128,13 +128,13 @@ class HTTPSitemapTests(SitemapTestsBase):
Site.objects.all().delete() Site.objects.all().delete()
self.assertRaises(ImproperlyConfigured, Sitemap().get_urls) self.assertRaises(ImproperlyConfigured, Sitemap().get_urls)
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
def test_sitemap_get_urls_no_site_2(self): def test_sitemap_get_urls_no_site_2(self):
""" """
Check we get ImproperlyConfigured when we don't pass a site object to Check we get ImproperlyConfigured when we don't pass a site object to
Sitemap.get_urls if Site objects exists, but the sites framework is not Sitemap.get_urls if Site objects exists, but the sites framework is not
actually installed. actually installed.
""" """
with app_cache._without_app('django.contrib.sites'):
self.assertRaises(ImproperlyConfigured, Sitemap().get_urls) self.assertRaises(ImproperlyConfigured, Sitemap().get_urls)
def test_sitemap_item(self): def test_sitemap_item(self):

View File

@ -1,22 +1,18 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.apps import app_cache
from django.conf import settings from django.conf import settings
from django.contrib.sites.models import Site, RequestSite, get_current_site from django.contrib.sites.models import Site, RequestSite, get_current_site
from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.http import HttpRequest from django.http import HttpRequest
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings from django.test.utils import modify_settings, override_settings
@modify_settings(INSTALLED_APPS={'append': 'django.contrib.sites'})
class SitesFrameworkTests(TestCase): class SitesFrameworkTests(TestCase):
def setUp(self): def setUp(self):
Site(id=settings.SITE_ID, domain="example.com", name="example.com").save() Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
self._with_sites = app_cache._begin_with_app('django.contrib.sites')
def tearDown(self):
app_cache._end_with_app(self._with_sites)
def test_save_another(self): def test_save_another(self):
# Regression for #17415 # Regression for #17415
@ -67,7 +63,7 @@ class SitesFrameworkTests(TestCase):
self.assertRaises(ObjectDoesNotExist, get_current_site, request) self.assertRaises(ObjectDoesNotExist, get_current_site, request)
# A RequestSite is returned if the sites framework is not installed # A RequestSite is returned if the sites framework is not installed
with app_cache._without_app('django.contrib.sites'): with self.modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'}):
site = get_current_site(request) site = get_current_site(request)
self.assertTrue(isinstance(site, RequestSite)) self.assertTrue(isinstance(site, RequestSite))
self.assertEqual(site.name, "example.com") self.assertEqual(site.name, "example.com")

View File

@ -1,13 +1,12 @@
import unittest import unittest
from django.apps import app_cache
from django.conf import settings from django.conf import settings
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.contrib.admindocs import utils from django.contrib.admindocs import utils
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings from django.test.utils import modify_settings, override_settings
class MiscTests(TestCase): class MiscTests(TestCase):
@ -17,12 +16,13 @@ class MiscTests(TestCase):
User.objects.create_superuser('super', None, 'secret') User.objects.create_superuser('super', None, 'secret')
self.client.login(username='super', password='secret') self.client.login(username='super', password='secret')
@modify_settings(INSTALLED_APPS={'remove': 'django.contrib.sites'})
@override_settings(SITE_ID=None) # will restore SITE_ID after the test
def test_no_sites_framework(self): def test_no_sites_framework(self):
""" """
Without the sites framework, should not access SITE_ID or Site Without the sites framework, should not access SITE_ID or Site
objects. Deleting settings is fine here as UserSettingsHolder is used. objects. Deleting settings is fine here as UserSettingsHolder is used.
""" """
with self.settings(SITE_ID=None), app_cache._without_app('django.contrib.sites'):
Site.objects.all().delete() Site.objects.all().delete()
del settings.SITE_ID del settings.SITE_ID
self.client.get('/admindocs/views/') # should not raise self.client.get('/admindocs/views/') # should not raise

View File

@ -2,9 +2,9 @@ from __future__ import unicode_literals
import os import os
import sys import sys
from unittest import TestCase
from django.apps import app_cache from django.apps import app_cache
from django.test import TestCase
from django.utils._os import upath from django.utils._os import upath
from django.utils import six from django.utils import six
@ -17,10 +17,9 @@ class EggLoadingTest(TestCase):
# The models need to be removed after the test in order to prevent bad # The models need to be removed after the test in order to prevent bad
# interactions with the flush operation in other tests. # interactions with the flush operation in other tests.
self._old_models = app_cache.app_configs['app_loading'].models.copy() self._old_models = app_cache.all_models['app_loading'].copy()
def tearDown(self): def tearDown(self):
app_cache.app_configs['app_loading'].models = self._old_models
app_cache.all_models['app_loading'] = self._old_models app_cache.all_models['app_loading'] = self._old_models
app_cache._get_models_cache = {} app_cache._get_models_cache = {}
@ -30,7 +29,7 @@ class EggLoadingTest(TestCase):
"""Models module can be loaded from an app in an egg""" """Models module can be loaded from an app in an egg"""
egg_name = '%s/modelapp.egg' % self.egg_dir egg_name = '%s/modelapp.egg' % self.egg_dir
sys.path.append(egg_name) sys.path.append(egg_name)
with app_cache._with_app('app_with_models'): with self.settings(INSTALLED_APPS=['app_with_models']):
models_module = app_cache.get_app_config('app_with_models').models_module models_module = app_cache.get_app_config('app_with_models').models_module
self.assertIsNotNone(models_module) self.assertIsNotNone(models_module)
@ -38,7 +37,7 @@ class EggLoadingTest(TestCase):
"""Loading an app from an egg that has no models returns no models (and no error)""" """Loading an app from an egg that has no models returns no models (and no error)"""
egg_name = '%s/nomodelapp.egg' % self.egg_dir egg_name = '%s/nomodelapp.egg' % self.egg_dir
sys.path.append(egg_name) sys.path.append(egg_name)
with app_cache._with_app('app_no_models'): with self.settings(INSTALLED_APPS=['app_no_models']):
models_module = app_cache.get_app_config('app_no_models').models_module models_module = app_cache.get_app_config('app_no_models').models_module
self.assertIsNone(models_module) self.assertIsNone(models_module)
@ -46,7 +45,7 @@ class EggLoadingTest(TestCase):
"""Models module can be loaded from an app located under an egg's top-level package""" """Models module can be loaded from an app located under an egg's top-level package"""
egg_name = '%s/omelet.egg' % self.egg_dir egg_name = '%s/omelet.egg' % self.egg_dir
sys.path.append(egg_name) sys.path.append(egg_name)
with app_cache._with_app('omelet.app_with_models'): with self.settings(INSTALLED_APPS=['omelet.app_with_models']):
models_module = app_cache.get_app_config('app_with_models').models_module models_module = app_cache.get_app_config('app_with_models').models_module
self.assertIsNotNone(models_module) self.assertIsNotNone(models_module)
@ -54,7 +53,7 @@ class EggLoadingTest(TestCase):
"""Loading an app with no models from under the top-level egg package generates no error""" """Loading an app with no models from under the top-level egg package generates no error"""
egg_name = '%s/omelet.egg' % self.egg_dir egg_name = '%s/omelet.egg' % self.egg_dir
sys.path.append(egg_name) sys.path.append(egg_name)
with app_cache._with_app('omelet.app_no_models'): with self.settings(INSTALLED_APPS=['omelet.app_no_models']):
models_module = app_cache.get_app_config('app_no_models').models_module models_module = app_cache.get_app_config('app_no_models').models_module
self.assertIsNone(models_module) self.assertIsNone(models_module)
@ -63,8 +62,8 @@ class EggLoadingTest(TestCase):
egg_name = '%s/brokenapp.egg' % self.egg_dir egg_name = '%s/brokenapp.egg' % self.egg_dir
sys.path.append(egg_name) sys.path.append(egg_name)
with six.assertRaisesRegex(self, ImportError, 'modelz'): with six.assertRaisesRegex(self, ImportError, 'modelz'):
with app_cache._with_app('broken_app'): with self.settings(INSTALLED_APPS=['broken_app']):
app_cache.get_app_config('omelet.app_no_models').models_module pass
class GetModelsTest(TestCase): class GetModelsTest(TestCase):

View File

@ -1,10 +1,9 @@
from django.apps import app_cache
from django.conf import settings from django.conf import settings
from django.contrib import comments from django.contrib import comments
from django.contrib.comments.models import Comment from django.contrib.comments.models import Comment
from django.contrib.comments.forms import CommentForm from django.contrib.comments.forms import CommentForm
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.test.utils import override_settings from django.test import modify_settings, override_settings
from django.utils import six from django.utils import six
from . import CommentTestCase from . import CommentTestCase
@ -35,16 +34,11 @@ class CommentAppAPITests(CommentTestCase):
self.assertEqual(comments.get_approve_url(c), "/approve/12345/") self.assertEqual(comments.get_approve_url(c), "/approve/12345/")
@modify_settings(INSTALLED_APPS={'append': 'comment_tests.custom_comments'})
@override_settings(COMMENTS_APP='comment_tests.custom_comments') @override_settings(COMMENTS_APP='comment_tests.custom_comments')
class CustomCommentTest(CommentTestCase): class CustomCommentTest(CommentTestCase):
urls = 'comment_tests.urls' urls = 'comment_tests.urls'
def setUp(self):
self._with_custom_comments = app_cache._begin_with_app('comment_tests.custom_comments')
def tearDown(self):
app_cache._end_with_app(self._with_custom_comments)
def testGetCommentApp(self): def testGetCommentApp(self):
from comment_tests import custom_comments from comment_tests import custom_comments
self.assertEqual(comments.get_comment_app(), custom_comments) self.assertEqual(comments.get_comment_app(), custom_comments)

View File

@ -8,7 +8,6 @@ import os
import pickle import pickle
from threading import local from threading import local
from django.apps import app_cache
from django.conf import settings from django.conf import settings
from django.template import Template, Context from django.template import Template, Context
from django.template.base import TemplateSyntaxError from django.template.base import TemplateSyntaxError
@ -1039,21 +1038,18 @@ class ResolutionOrderI18NTests(TransRealMixin, TestCase):
class AppResolutionOrderI18NTests(ResolutionOrderI18NTests): class AppResolutionOrderI18NTests(ResolutionOrderI18NTests):
def test_app_translation(self): def test_app_translation(self):
# This test relies on an implementation detail, namely the fact that
# _with_app adds the app at the list. Adjust the test if this changes.
# Original translation. # Original translation.
self.assertUgettext('Date/time', 'Datum/Zeit') self.assertUgettext('Date/time', 'Datum/Zeit')
# Different translation. # Different translation.
with app_cache._with_app('i18n.resolution'): with self.modify_settings(INSTALLED_APPS={'append': 'i18n.resolution'}):
self.flush_caches() self.flush_caches()
activate('de') activate('de')
# Doesn't work because it's added later in the list. # Doesn't work because it's added later in the list.
self.assertUgettext('Date/time', 'Datum/Zeit') self.assertUgettext('Date/time', 'Datum/Zeit')
with app_cache._without_app('admin'): with self.modify_settings(INSTALLED_APPS={'remove': 'django.contrib.admin'}):
self.flush_caches() self.flush_caches()
activate('de') activate('de')
@ -1068,7 +1064,7 @@ class LocalePathsResolutionOrderI18NTests(ResolutionOrderI18NTests):
self.assertUgettext('Time', 'LOCALE_PATHS') self.assertUgettext('Time', 'LOCALE_PATHS')
def test_locale_paths_override_app_translation(self): def test_locale_paths_override_app_translation(self):
with app_cache._with_app('i18n.resolution'): with self.settings(INSTALLED_APPS=['i18n.resolution']):
self.assertUgettext('Time', 'LOCALE_PATHS') self.assertUgettext('Time', 'LOCALE_PATHS')

View File

@ -3,7 +3,7 @@ import unittest
from django.apps import app_cache from django.apps import app_cache
from django.core.management.validation import get_validation_errors from django.core.management.validation import get_validation_errors
from django.test.utils import override_settings from django.test import override_settings
from django.utils.six import StringIO from django.utils.six import StringIO
@ -26,12 +26,12 @@ class InvalidModelTestCase(unittest.TestCase):
# easier to set this up as an override than to require every developer # easier to set this up as an override than to require every developer
# to specify a value in their test settings. # to specify a value in their test settings.
@override_settings( @override_settings(
INSTALLED_APPS=['invalid_models_tests.invalid_models'],
TEST_SWAPPED_MODEL='invalid_models.ReplacementModel', TEST_SWAPPED_MODEL='invalid_models.ReplacementModel',
TEST_SWAPPED_MODEL_BAD_VALUE='not-a-model', TEST_SWAPPED_MODEL_BAD_VALUE='not-a-model',
TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target', TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target',
) )
def test_invalid_models(self): def test_invalid_models(self):
with app_cache._with_app("invalid_models_tests.invalid_models"):
module = app_cache.get_app_config("invalid_models").models_module module = app_cache.get_app_config("invalid_models").models_module
get_validation_errors(self.stdout, module) get_validation_errors(self.stdout, module)

View File

@ -5,7 +5,6 @@ from __future__ import unicode_literals
import datetime import datetime
import os import os
from django.apps import app_cache
from django.core.validators import RegexValidator, EmailValidator from django.core.validators import RegexValidator, EmailValidator
from django.db import models, migrations from django.db import models, migrations
from django.db.migrations.writer import MigrationWriter from django.db.migrations.writer import MigrationWriter
@ -123,7 +122,7 @@ class WriterTests(TestCase):
base_dir = os.path.dirname(os.path.dirname(__file__)) base_dir = os.path.dirname(os.path.dirname(__file__))
for app in test_apps: for app in test_apps:
with app_cache._with_app(app): with self.modify_settings(INSTALLED_APPS={'append': app}):
migration = migrations.Migration('0001_initial', app.split('.')[-1]) migration = migrations.Migration('0001_initial', app.split('.')[-1])
expected_path = os.path.join(base_dir, *(app.split('.') + ['migrations', '0001_initial.py'])) expected_path = os.path.join(base_dir, *(app.split('.') + ['migrations', '0001_initial.py']))
writer = MigrationWriter(migration) writer = MigrationWriter(migration)

View File

@ -3,7 +3,6 @@ from __future__ import unicode_literals
import os import os
import sys import sys
from django.apps import app_cache
from django.core.management import call_command from django.core.management import call_command
from django.test import TestCase, TransactionTestCase from django.test import TestCase, TransactionTestCase
from django.utils._os import upath from django.utils._os import upath
@ -28,7 +27,7 @@ class ProxyModelInheritanceTests(TransactionTestCase):
sys.path = self.old_sys_path sys.path = self.old_sys_path
def test_table_exists(self): def test_table_exists(self):
with app_cache._with_app('app1'), app_cache._with_app('app2'): with self.modify_settings(INSTALLED_APPS={'append': ['app1', 'app2']}):
call_command('migrate', verbosity=0) call_command('migrate', verbosity=0)
from .app1.models import ProxyModel from .app1.models import ProxyModel
from .app2.models import NiceModel from .app2.models import NiceModel

View File

@ -86,7 +86,7 @@ def get_installed():
def setup(verbosity, test_labels): def setup(verbosity, test_labels):
import django import django
from django.apps import app_cache from django.apps import app_cache, AppConfig
from django.conf import settings from django.conf import settings
from django.test import TransactionTestCase, TestCase from django.test import TransactionTestCase, TestCase
@ -165,9 +165,11 @@ def setup(verbosity, test_labels):
if verbosity >= 2: if verbosity >= 2:
print("Importing application %s" % module_name) print("Importing application %s" % module_name)
# HACK. # HACK.
app_cache._begin_with_app(module_label)
if module_label not in settings.INSTALLED_APPS: if module_label not in settings.INSTALLED_APPS:
settings.INSTALLED_APPS.append(module_label) settings.INSTALLED_APPS.append(module_label)
app_config = AppConfig.create(module_label)
app_config.import_models(app_cache.all_models[app_config.label])
app_cache.app_configs[app_config.label] = app_config
return state return state

View File

@ -20,12 +20,10 @@ except ImportError:
pkg_resources = None pkg_resources = None
from django.apps import app_cache
from django.template import TemplateDoesNotExist, Context from django.template import TemplateDoesNotExist, Context
from django.template.loaders.eggs import Loader as EggLoader from django.template.loaders.eggs import Loader as EggLoader
from django.template import loader from django.template import loader
from django.test import TestCase from django.test import TestCase, override_settings
from django.test.utils import override_settings
from django.utils import six from django.utils import six
from django.utils._os import upath from django.utils._os import upath
from django.utils.six import StringIO from django.utils.six import StringIO
@ -78,21 +76,21 @@ class EggLoaderTest(TestCase):
os.path.normcase('templates/x.txt'): StringIO("x"), os.path.normcase('templates/x.txt'): StringIO("x"),
}) })
@override_settings(INSTALLED_APPS=['egg_empty'])
def test_empty(self): def test_empty(self):
"Loading any template on an empty egg should fail" "Loading any template on an empty egg should fail"
with app_cache._with_app('egg_empty'):
egg_loader = EggLoader() egg_loader = EggLoader()
self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html") self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html")
@override_settings(INSTALLED_APPS=['egg_1'])
def test_non_existing(self): def test_non_existing(self):
"Template loading fails if the template is not in the egg" "Template loading fails if the template is not in the egg"
with app_cache._with_app('egg_1'):
egg_loader = EggLoader() egg_loader = EggLoader()
self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html") self.assertRaises(TemplateDoesNotExist, egg_loader.load_template_source, "not-existing.html")
@override_settings(INSTALLED_APPS=['egg_1'])
def test_existing(self): def test_existing(self):
"A template can be loaded from an egg" "A template can be loaded from an egg"
with app_cache._with_app('egg_1'):
egg_loader = EggLoader() egg_loader = EggLoader()
contents, template_name = egg_loader.load_template_source("y.html") contents, template_name = egg_loader.load_template_source("y.html")
self.assertEqual(contents, "y") self.assertEqual(contents, "y")

View File

@ -16,7 +16,6 @@ import unittest
import warnings import warnings
from django import template from django import template
from django.apps import app_cache
from django.core import urlresolvers from django.core import urlresolvers
from django.template import (base as template_base, loader, Context, from django.template import (base as template_base, loader, Context,
RequestContext, Template, TemplateSyntaxError) RequestContext, Template, TemplateSyntaxError)
@ -1879,10 +1878,10 @@ class TemplateTagLoading(TestCase):
egg_name = '%s/tagsegg.egg' % self.egg_dir egg_name = '%s/tagsegg.egg' % self.egg_dir
sys.path.append(egg_name) sys.path.append(egg_name)
with self.assertRaises(template.TemplateSyntaxError): with self.assertRaises(template.TemplateSyntaxError):
with app_cache._with_app('tagsegg'): with self.settings(INSTALLED_APPS=['tagsegg']):
template.Template(ttext) template.Template(ttext)
try: try:
with app_cache._with_app('tagsegg'): with self.settings(INSTALLED_APPS=['tagsegg']):
template.Template(ttext) template.Template(ttext)
except template.TemplateSyntaxError as e: except template.TemplateSyntaxError as e:
self.assertTrue('ImportError' in e.args[0]) self.assertTrue('ImportError' in e.args[0])
@ -1892,7 +1891,7 @@ class TemplateTagLoading(TestCase):
ttext = "{% load working_egg %}" ttext = "{% load working_egg %}"
egg_name = '%s/tagsegg.egg' % self.egg_dir egg_name = '%s/tagsegg.egg' % self.egg_dir
sys.path.append(egg_name) sys.path.append(egg_name)
with app_cache._with_app('tagsegg'): with self.settings(INSTALLED_APPS=['tagsegg']):
template.Template(ttext) template.Template(ttext)

View File

@ -1,7 +1,6 @@
import os import os
from django import conf from django import conf
from django.apps import app_cache
from django.contrib import admin from django.contrib import admin
from django.test import TestCase, override_settings from django.test import TestCase, override_settings
from django.utils.autoreload import gen_filenames from django.utils.autoreload import gen_filenames
@ -28,6 +27,7 @@ class TestFilenameGenerator(TestCase):
self.assertIn(os.path.join(LOCALE_PATH, 'nl', 'LC_MESSAGES', 'django.mo'), self.assertIn(os.path.join(LOCALE_PATH, 'nl', 'LC_MESSAGES', 'django.mo'),
filenames) filenames)
@override_settings(INSTALLED_APPS=[])
def test_project_root_locale(self): def test_project_root_locale(self):
""" """
Test that gen_filenames also yields from the current directory (project Test that gen_filenames also yields from the current directory (project
@ -36,9 +36,6 @@ class TestFilenameGenerator(TestCase):
old_cwd = os.getcwd() old_cwd = os.getcwd()
os.chdir(os.path.dirname(__file__)) os.chdir(os.path.dirname(__file__))
try: try:
# Remove the current app from the app cache to guarantee that the
# files will be found thanks to the current working directory.
with app_cache._empty():
filenames = list(gen_filenames()) filenames = list(gen_filenames())
self.assertIn( self.assertIn(
os.path.join(LOCALE_PATH, 'nl', 'LC_MESSAGES', 'django.mo'), os.path.join(LOCALE_PATH, 'nl', 'LC_MESSAGES', 'django.mo'),
@ -46,11 +43,11 @@ class TestFilenameGenerator(TestCase):
finally: finally:
os.chdir(old_cwd) os.chdir(old_cwd)
@override_settings(INSTALLED_APPS=['django.contrib.admin'])
def test_app_locales(self): def test_app_locales(self):
""" """
Test that gen_filenames also yields from locale dirs in installed apps. Test that gen_filenames also yields from locale dirs in installed apps.
""" """
with app_cache._empty(), app_cache._with_app('django.contrib.admin'):
filenames = list(gen_filenames()) filenames = list(gen_filenames())
self.assertIn(os.path.join(os.path.dirname(admin.__file__), 'locale', self.assertIn(os.path.join(os.path.dirname(admin.__file__), 'locale',
'nl', 'LC_MESSAGES', 'django.mo'), 'nl', 'LC_MESSAGES', 'django.mo'),

View File

@ -5,9 +5,8 @@ import sys
import unittest import unittest
from zipimport import zipimporter from zipimport import zipimporter
from django.apps import app_cache
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.test import SimpleTestCase from django.test import SimpleTestCase, modify_settings
from django.utils import six from django.utils import six
from django.utils.module_loading import autodiscover_modules, import_by_path, module_has_submodule from django.utils.module_loading import autodiscover_modules, import_by_path, module_has_submodule
from django.utils._os import upath from django.utils._os import upath
@ -135,14 +134,9 @@ class ModuleImportTestCase(unittest.TestCase):
'Should have more than the calling frame in the traceback.') 'Should have more than the calling frame in the traceback.')
@modify_settings(INSTALLED_APPS={'append': 'utils_tests.test_module'})
class AutodiscoverModulesTestCase(SimpleTestCase): class AutodiscoverModulesTestCase(SimpleTestCase):
def setUp(self):
self._with_test_module = app_cache._begin_with_app('utils_tests.test_module')
def tearDown(self):
app_cache._end_with_app(self._with_test_module)
def test_autodiscover_modules_found(self): def test_autodiscover_modules_found(self):
autodiscover_modules('good_module') autodiscover_modules('good_module')

View File

@ -4,11 +4,10 @@ import os
from os import path from os import path
import unittest import unittest
from django.apps import app_cache
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test import LiveServerTestCase, TestCase from django.test import (
from django.test.utils import override_settings LiveServerTestCase, TestCase, modify_settings, override_settings)
from django.utils import six from django.utils import six
from django.utils._os import upath from django.utils._os import upath
from django.utils.translation import override from django.utils.translation import override
@ -110,13 +109,13 @@ class JsI18NTests(TestCase):
response = self.client.get('/views/jsi18n/') response = self.client.get('/views/jsi18n/')
self.assertNotContains(response, 'Choisir une heure') self.assertNotContains(response, 'Choisir une heure')
@modify_settings(INSTALLED_APPS={'append': 'view_tests.app0'})
def test_nonenglish_default_english_userpref(self): def test_nonenglish_default_english_userpref(self):
""" """
Same as above with the difference that there IS an 'en' translation Same as above with the difference that there IS an 'en' translation
available. The Javascript i18n view must return a NON empty language catalog available. The Javascript i18n view must return a NON empty language catalog
with the proper English translations. See #13726 for more details. with the proper English translations. See #13726 for more details.
""" """
with app_cache._with_app('view_tests.app0'):
with self.settings(LANGUAGE_CODE='fr'), override('en-us'): with self.settings(LANGUAGE_CODE='fr'), override('en-us'):
response = self.client.get('/views/jsi18n_english_translation/') response = self.client.get('/views/jsi18n_english_translation/')
self.assertContains(response, javascript_quote('this app0 string is to be translated')) self.assertContains(response, javascript_quote('this app0 string is to be translated'))
@ -141,6 +140,7 @@ class JsI18NTestsMultiPackage(TestCase):
Tests for django views in django/views/i18n.py that need to change Tests for django views in django/views/i18n.py that need to change
settings.LANGUAGE_CODE and merge JS translation from several packages. settings.LANGUAGE_CODE and merge JS translation from several packages.
""" """
@modify_settings(INSTALLED_APPS={'append': ['view_tests.app1', 'view_tests.app2']})
def testI18NLanguageEnglishDefault(self): def testI18NLanguageEnglishDefault(self):
""" """
Check if the JavaScript i18n view returns a complete language catalog Check if the JavaScript i18n view returns a complete language catalog
@ -149,17 +149,16 @@ class JsI18NTestsMultiPackage(TestCase):
translations of multiple Python packages is requested. See #13388, translations of multiple Python packages is requested. See #13388,
#3594 and #13514 for more details. #3594 and #13514 for more details.
""" """
with app_cache._with_app('view_tests.app1'), app_cache._with_app('view_tests.app2'):
with self.settings(LANGUAGE_CODE='en-us'), override('fr'): with self.settings(LANGUAGE_CODE='en-us'), override('fr'):
response = self.client.get('/views/jsi18n_multi_packages1/') response = self.client.get('/views/jsi18n_multi_packages1/')
self.assertContains(response, javascript_quote('il faut traduire cette chaîne de caractères de app1')) self.assertContains(response, javascript_quote('il faut traduire cette chaîne de caractères de app1'))
@modify_settings(INSTALLED_APPS={'append': ['view_tests.app3', 'view_tests.app4']})
def testI18NDifferentNonEnLangs(self): def testI18NDifferentNonEnLangs(self):
""" """
Similar to above but with neither default or requested language being Similar to above but with neither default or requested language being
English. English.
""" """
with app_cache._with_app('view_tests.app3'), app_cache._with_app('view_tests.app4'):
with self.settings(LANGUAGE_CODE='fr'), override('es-ar'): with self.settings(LANGUAGE_CODE='fr'), override('es-ar'):
response = self.client.get('/views/jsi18n_multi_packages2/') response = self.client.get('/views/jsi18n_multi_packages2/')
self.assertContains(response, javascript_quote('este texto de app3 debe ser traducido')) self.assertContains(response, javascript_quote('este texto de app3 debe ser traducido'))