Code

Ticket #9310: named_404_with_test.diff

File named_404_with_test.diff, 7.0 KB (added by tobias, 4 years ago)

REALLY updated the patch to latest trunk

Line 
1diff -r da07240fd0ca django/core/urlresolvers.py
2--- a/django/core/urlresolvers.py       Fri Sep 10 20:13:28 2010 -0700
3+++ b/django/core/urlresolvers.py       Fri Sep 10 20:40:17 2010 -0700
4@@ -252,9 +252,9 @@
5                 except Resolver404, e:
6                     sub_tried = e.args[0].get('tried')
7                     if sub_tried is not None:
8-                        tried.extend([(pattern.regex.pattern + '   ' + t) for t in sub_tried])
9+                        tried.extend([[pattern] + t for t in sub_tried])
10                     else:
11-                        tried.append(pattern.regex.pattern)
12+                        tried.append([pattern])
13                 else:
14                     if sub_match:
15                         sub_match_dict = dict([(smart_str(k), v) for k, v in match.groupdict().items()])
16@@ -262,7 +262,7 @@
17                         for k, v in sub_match.kwargs.iteritems():
18                             sub_match_dict[smart_str(k)] = v
19                         return ResolverMatch(sub_match.func, sub_match.args, sub_match_dict, sub_match.url_name, self.app_name or sub_match.app_name, [self.namespace] + sub_match.namespaces)
20-                    tried.append(pattern.regex.pattern)
21+                    tried.append([pattern])
22             raise Resolver404({'tried': tried, 'path': new_path})
23         raise Resolver404({'path' : path})
24 
25diff -r da07240fd0ca django/views/debug.py
26--- a/django/views/debug.py     Fri Sep 10 20:13:28 2010 -0700
27+++ b/django/views/debug.py     Fri Sep 10 20:40:17 2010 -0700
28@@ -778,7 +778,12 @@
29       </p>
30       <ol>
31         {% for pattern in urlpatterns %}
32-          <li>{{ pattern }}</li>
33+          <li>
34+            {% for pat in pattern %}
35+                {{ pat.regex.pattern }}
36+                {% if forloop.last and pat.name %}[name='{{ pat.name }}']{% endif %}
37+            {% endfor %}
38+          </li>
39         {% endfor %}
40       </ol>
41       <p>The current URL, <code>{{ request_path|escape }}</code>, didn't match any of these.</p>
42diff -r da07240fd0ca tests/regressiontests/urlpatterns_reverse/included_named_urls.py
43--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
44+++ b/tests/regressiontests/urlpatterns_reverse/included_named_urls.py  Fri Sep 10 20:40:17 2010 -0700
45@@ -0,0 +1,10 @@
46+from django.conf.urls.defaults import *
47+from views import empty_view
48+
49+urlpatterns = patterns('',
50+    url(r'^$', empty_view, name="named-url3"),
51+    url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url4"),
52+    url(r'^(?P<one>\d+)|(?P<two>\d+)/$', empty_view),
53+    (r'^included/', include('regressiontests.urlpatterns_reverse.included_named_urls2')),
54+)
55+
56diff -r da07240fd0ca tests/regressiontests/urlpatterns_reverse/included_named_urls2.py
57--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
58+++ b/tests/regressiontests/urlpatterns_reverse/included_named_urls2.py Fri Sep 10 20:40:17 2010 -0700
59@@ -0,0 +1,9 @@
60+from django.conf.urls.defaults import *
61+from views import empty_view
62+
63+urlpatterns = patterns('',
64+    url(r'^$', empty_view, name="named-url5"),
65+    url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url6"),
66+    url(r'^(?P<one>\d+)|(?P<two>\d+)/$', empty_view),
67+)
68+
69diff -r da07240fd0ca tests/regressiontests/urlpatterns_reverse/named_urls.py
70--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
71+++ b/tests/regressiontests/urlpatterns_reverse/named_urls.py   Fri Sep 10 20:40:17 2010 -0700
72@@ -0,0 +1,9 @@
73+from django.conf.urls.defaults import *
74+from views import empty_view
75+
76+urlpatterns = patterns('',
77+    url(r'^$', empty_view, name="named-url1"),
78+    url(r'^extra/(?P<extra>\w+)/$', empty_view, name="named-url2"),
79+    url(r'^(?P<one>\d+)|(?P<two>\d+)/$', empty_view),
80+    (r'^included/', include('regressiontests.urlpatterns_reverse.included_named_urls')),
81+)
82diff -r da07240fd0ca tests/regressiontests/urlpatterns_reverse/tests.py
83--- a/tests/regressiontests/urlpatterns_reverse/tests.py        Fri Sep 10 20:13:28 2010 -0700
84+++ b/tests/regressiontests/urlpatterns_reverse/tests.py        Fri Sep 10 20:40:17 2010 -0700
85@@ -18,7 +18,9 @@
86 
87 from django.conf import settings
88 from django.core.exceptions import ImproperlyConfigured
89-from django.core.urlresolvers import reverse, resolve, NoReverseMatch, Resolver404, ResolverMatch
90+from django.core.urlresolvers import reverse, resolve, NoReverseMatch,\
91+                                     Resolver404, ResolverMatch,\
92+                                     RegexURLResolver, RegexURLPattern
93 from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
94 from django.shortcuts import redirect
95 from django.test import TestCase
96@@ -172,6 +174,42 @@
97         self.assertRaises(Resolver404, resolve, 'a')
98         self.assertRaises(Resolver404, resolve, '\\')
99         self.assertRaises(Resolver404, resolve, '.')
100+       
101+    def test_404_tried_urls_have_names(self):
102+        """
103+        Verifies that the list of URLs that come back from a Resolver404
104+        exception contains a list in the right format for printing out in
105+        the DEBUG 404 page with both the patterns and URL names, if available.
106+        """
107+        urls = 'regressiontests.urlpatterns_reverse.named_urls'
108+        # this list matches the expected URL types and names returned when
109+        # you try to resolve a non-existent URL in the first level of included
110+        # URLs in named_urls.py (e.g., '/included/non-existent-url')
111+        url_types_names = [
112+            [{'type': RegexURLPattern, 'name': 'named-url1'}],
113+            [{'type': RegexURLPattern, 'name': 'named-url2'}],
114+            [{'type': RegexURLPattern, 'name': None}],
115+            [{'type': RegexURLResolver}, {'type': RegexURLPattern, 'name': 'named-url3'}],
116+            [{'type': RegexURLResolver}, {'type': RegexURLPattern, 'name': 'named-url4'}],
117+            [{'type': RegexURLResolver}, {'type': RegexURLPattern, 'name': None}],
118+            [{'type': RegexURLResolver}, {'type': RegexURLResolver}],
119+        ]
120+        try:
121+            resolve('/included/non-existent-url', urlconf=urls)
122+            self.fail('resolve did not raise a 404')
123+        except Resolver404, e:
124+            # make sure we at least matched the root ('/') url resolver:
125+            self.assertTrue('tried' in e.args[0])
126+            tried = e.args[0]['tried']
127+            self.assertEqual(len(e.args[0]['tried']), len(url_types_names), 'Wrong number of tried URLs returned.  Expected %s, got %s.' % (len(url_types_names), len(e.args[0]['tried'])))
128+            for tried, expected in zip(e.args[0]['tried'], url_types_names):
129+                for t, e in zip(tried, expected):
130+                    self.assertTrue(isinstance(t, e['type']), '%s is not an instance of %s' % (t, e['type']))
131+                    if 'name' in e:
132+                        if not e['name']:
133+                            self.assertTrue(t.name is None, 'Expected no URL name but found %s.' % t.name)
134+                        else:
135+                            self.assertEqual(t.name, e['name'], 'Wrong URL name.  Expected "%s", got "%s".' % (e['name'], t.name))
136 
137 class ReverseShortcutTests(TestCase):
138     urls = 'regressiontests.urlpatterns_reverse.urls'