Ticket #11077: test_combine_urlconfs.diff

File test_combine_urlconfs.diff, 8.7 KB (added by Cory Walker, 14 years ago)

The complete patch

  • django/test/testcases.py

     
    11import re
     2import sys
     3import imp
    24import unittest
    35from urlparse import urlsplit, urlunsplit
    46from xml.dom.minidom import parseString, Node
     
    1315from django.test.client import Client
    1416from django.utils import simplejson
    1517from django.utils.encoding import smart_str
     18from django.utils.importlib import import_module
    1619
    1720try:
    1821    all
     
    210213            transaction.rollback_unless_managed(using=conn)
    211214
    212215class TransactionTestCase(unittest.TestCase):
     216    # This can be modified to bypass what the settings are when running a test.
     217    combine_urls = False
     218    combine_urls_with = None
     219
    213220    def _pre_setup(self):
    214221        """Performs any pre-test setup. This includes:
    215222
     
    242249    def _urlconf_setup(self):
    243250        if hasattr(self, 'urls'):
    244251            self._old_root_urlconf = settings.ROOT_URLCONF
    245             settings.ROOT_URLCONF = self.urls
     252            if settings.TEST_COMBINE_URLCONFS or self.combine_urls:
     253                # Put the module instance of self.urls into specified_urlconf.
     254                if not isinstance(self.urls, basestring):
     255                    specified_urlconf = self.urls
     256                else:
     257                    specified_urlconf = import_module(self.urls)
     258                # Choose between settings.TEST_COMBINE_URLCONFS_WITH and
     259                # settings.ROOT_URLCONF.
     260                urls_to_combine = self.combine_urls_with or \
     261                    settings.TEST_COMBINE_URLCONFS_WITH or settings.ROOT_URLCONF
     262                # Do the above action, this time with urls_to_combine.
     263                if not isinstance(urls_to_combine, basestring):
     264                    extra_urlconf = urls_to_combine
     265                else:
     266                    extra_urlconf = import_module(urls_to_combine)
     267                # Create a dynamic URLconf module that combines the urlpatterns.
     268                # of specified_urlconf and extra_urlconf
     269                dynamic_urlconf_name = 'dynamic_urls'
     270                dynamic_urlconf = imp.new_module(dynamic_urlconf_name)
     271                dynamic_urlconf.urlpatterns = specified_urlconf.urlpatterns + \
     272                        extra_urlconf.urlpatterns
     273                    # Also combine handler404 and 500, favoring specified_urlconf
     274                handler404 = getattr(specified_urlconf, 'handler404', None) or \
     275                    getattr(extra_urlconf, 'handler404', None)
     276                if handler404:
     277                    dynamic_urlconf.handler404 = handler404
     278                handler500 = getattr(specified_urlconf, 'handler500', None) or \
     279                    getattr(extra_urlconf, 'handler500', None)
     280                if handler500:
     281                    dynamic_urlconf.handler500 = handler500
     282                # Add our dynamic_urlconf to sys.modules and set
     283                # settings.ROOT_URLCONF to it.
     284                sys.modules[dynamic_urlconf_name] = dynamic_urlconf
     285                settings.ROOT_URLCONF = dynamic_urlconf
     286            else:
     287                settings.ROOT_URLCONF = self.urls
    246288            clear_url_caches()
    247289
    248290    def __call__(self, result=None):
  • django/conf/global_settings.py

     
    506506TEST_DATABASE_CHARSET = None
    507507TEST_DATABASE_COLLATION = None
    508508
     509# If true, the testing framework will combine the URLconf instead of overwrite
     510# it if a TestCase.urls is specified
     511TEST_COMBINE_URLCONFS = False
     512
     513# The URLconf to be combined with the TestCase.urls setting. If None, the
     514# ROOT_URLCONF specified in settings.py will be used instead.
     515TEST_COMBINE_URLCONFS_WITH = None
     516
    509517############
    510518# FIXTURES #
    511519############
  • tests/regressiontests/test_client_regress/combine_urls.py

     
     1from django.conf.urls.defaults import *
     2import views
     3
     4urlpatterns = patterns('',
     5    url(r'^custom_arg_view/(?P<name>.+)/$', views.view_with_argument, name='custom_arg_view'),
     6)
  • tests/regressiontests/test_client_regress/models.py

     
    583583        url = reverse('arg_view', args=['somename'])
    584584        self.assertEquals(url, '/arg_view/somename/')
    585585
     586class UrlconfCombinationTests(TestCase):
     587    urls = 'regressiontests.test_client_regress.combine_urls'
     588    combine_urls = True
     589
     590    def test_urlconf_was_changed(self):
     591        "Should have access to urls from combine_urls and ROOT_URLCONF"
     592        url = reverse('arg_view', args=['somename'])
     593        self.assertEquals(url, '/test_client_regress/arg_view/somename/')
     594        url = reverse('custom_arg_view', args=['somename'])
     595        self.assertEquals(url, '/custom_arg_view/somename/')
     596
     597class UrlconfCombinationWithTests(TestCase):
     598    urls = 'regressiontests.test_client_regress.combine_urls'
     599    combine_urls_with = 'regressiontests.test_client_regress.urls'
     600    combine_urls = True
     601
     602    def test_urlconf_was_changed(self):
     603        "Should have access to test_client_regress.combine_urls and test_client_regress.urls"
     604        url = reverse('arg_view', args=['somename'])
     605        self.assertEquals(url, '/arg_view/somename/')
     606        url = reverse('custom_arg_view', args=['somename'])
     607        self.assertEquals(url, '/custom_arg_view/somename/')
     608
    586609# This test needs to run *after* UrlconfSubstitutionTests; the zz prefix in the
    587610# name is to ensure alphabetical ordering.
    588611class zzUrlconfSubstitutionTests(TestCase):
  • docs/topics/testing.txt

     
    10541054This test case will use the contents of ``myapp.test_urls`` as the
    10551055URLconf for the duration of the test case.
    10561056
     1057.. versionadded:: 1.2
     1058
     1059The use of ``TestCase.urls`` has a downside, though. Since it overrides
     1060``ROOT_URLCONF``, your project's other urls will not be accessible. This is
     1061normally not a problem, but custom templates with reverses to external apps will
     1062cause the tests to raise ``NoReverseMatch`` exceptions. This problem can happen
     1063with :mod:`django.contrib.auth` and other apps that support custom templates and
     1064set ``TestCase.urls``. Custom templates that include a ``base.html`` with links to
     1065various places around the site are common sources of this problem.
     1066
     1067This situation can be fixed by combining the ``TestCase.urls`` with your
     1068project's ``ROOT_URLCONF``. You can also choose to combine a custom URLconf
     1069designed specifically for testing. See :setting:`TEST_COMBINE_URLCONFS` and
     1070:setting:`TEST_COMBINE_URLCONFS_WITH` for more information.
     1071
    10571072.. _emptying-test-outbox:
    10581073
    10591074Multi-database support
  • docs/ref/settings.txt

     
    14201420Output, as a string, that the template system should use for invalid (e.g.
    14211421misspelled) variables. See :ref:`invalid-template-variables`..
    14221422
     1423.. setting:: TEST_COMBINE_URLCONFS
     1424
     1425TEST_COMBINE_URLCONFS
     1426---------------------
     1427
     1428.. versionadded:: 1.2
     1429
     1430Default: ``False``
     1431
     1432If ``True``, the testing framework will combine the URLconf instead of overwrite
     1433it if a ``TestCase.urls`` is specified. The URLconf merged into the
     1434``TestCase.urls`` will be :setting:`ROOT_URLCONF` unless
     1435:setting:`TEST_COMBINE_URLCONFS_WITH` is set.
     1436
     1437This setting is useful for cases where apps like :mod:`django.contrib.auth` set
     1438``TestCase.urls`` to override the :setting:`ROOT_URLCONF` with a custom testing
     1439URLconf. This setting will fix the problem where custom templates with reverses
     1440to external apps cause the tests to fail with ``NoReverseMatch`` errors.
     1441
     1442.. setting:: TEST_COMBINE_URLCONFS_WITH
     1443
     1444TEST_COMBINE_URLCONFS_WITH
     1445--------------------------
     1446
     1447.. versionadded:: 1.2
     1448
     1449Default: ``None``
     1450
     1451The URLconf to be combined with the ``TestCase.urls`` setting if it is set. If
     1452``None``, the :setting:`ROOT_URLCONF` will be used instead. This setting will
     1453only be used if :setting:`TEST_COMBINE_URLCONFS` is ``True``. This can either be
     1454a string pointing to a module or an actual module, much like
     1455:setting:`ROOT_URLCONF`.
     1456
    14231457.. setting:: TEST_RUNNER
    14241458
    14251459TEST_RUNNER
Back to Top