mirror of https://github.com/django/django.git
Refs #27804 -- Used subTest() in urlpatterns_reverse tests.
This commit is contained in:
parent
4af88ccbe6
commit
ceb5f1c9bf
|
@ -277,12 +277,13 @@ class URLPatternReverse(SimpleTestCase):
|
||||||
|
|
||||||
def test_urlpattern_reverse(self):
|
def test_urlpattern_reverse(self):
|
||||||
for name, expected, args, kwargs in test_data:
|
for name, expected, args, kwargs in test_data:
|
||||||
try:
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
got = reverse(name, args=args, kwargs=kwargs)
|
try:
|
||||||
except NoReverseMatch:
|
got = reverse(name, args=args, kwargs=kwargs)
|
||||||
self.assertEqual(expected, NoReverseMatch)
|
except NoReverseMatch:
|
||||||
else:
|
self.assertEqual(NoReverseMatch, expected)
|
||||||
self.assertEqual(got, expected)
|
else:
|
||||||
|
self.assertEqual(got, expected)
|
||||||
|
|
||||||
def test_reverse_none(self):
|
def test_reverse_none(self):
|
||||||
# Reversing None should raise an error, not return the last un-named view.
|
# Reversing None should raise an error, not return the last un-named view.
|
||||||
|
@ -382,9 +383,15 @@ class ResolverTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_resolver_reverse(self):
|
def test_resolver_reverse(self):
|
||||||
resolver = get_resolver('urlpatterns_reverse.named_urls')
|
resolver = get_resolver('urlpatterns_reverse.named_urls')
|
||||||
self.assertEqual(resolver.reverse('named-url1'), '')
|
test_urls = [
|
||||||
self.assertEqual(resolver.reverse('named-url2', 'arg'), 'extra/arg/')
|
# (name, args, kwargs, expected)
|
||||||
self.assertEqual(resolver.reverse('named-url2', extra='arg'), 'extra/arg/')
|
('named-url1', (), {}, ''),
|
||||||
|
('named-url2', ('arg',), {}, 'extra/arg/'),
|
||||||
|
('named-url2', (), {'extra': 'arg'}, 'extra/arg/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(resolver.reverse(name, *args, **kwargs), expected)
|
||||||
|
|
||||||
def test_resolver_reverse_conflict(self):
|
def test_resolver_reverse_conflict(self):
|
||||||
"""
|
"""
|
||||||
|
@ -392,16 +399,22 @@ class ResolverTests(SimpleTestCase):
|
||||||
pattern takes precedence for conflicting names.
|
pattern takes precedence for conflicting names.
|
||||||
"""
|
"""
|
||||||
resolver = get_resolver('urlpatterns_reverse.named_urls_conflict')
|
resolver = get_resolver('urlpatterns_reverse.named_urls_conflict')
|
||||||
# Without arguments, the last URL in urlpatterns has precedence.
|
test_urls = [
|
||||||
self.assertEqual(resolver.reverse('name-conflict'), 'conflict/')
|
# (name, args, kwargs, expected)
|
||||||
# With an arg, the last URL in urlpatterns has precedence.
|
# Without arguments, the last URL in urlpatterns has precedence.
|
||||||
self.assertEqual(resolver.reverse('name-conflict', 'arg'), 'conflict-last/arg/')
|
('name-conflict', (), {}, 'conflict/'),
|
||||||
# With a kwarg, other url()s can be reversed.
|
# With an arg, the last URL in urlpatterns has precedence.
|
||||||
self.assertEqual(resolver.reverse('name-conflict', first='arg'), 'conflict-first/arg/')
|
('name-conflict', ('arg',), {}, 'conflict-last/arg/'),
|
||||||
self.assertEqual(resolver.reverse('name-conflict', middle='arg'), 'conflict-middle/arg/')
|
# With a kwarg, other url()s can be reversed.
|
||||||
self.assertEqual(resolver.reverse('name-conflict', last='arg'), 'conflict-last/arg/')
|
('name-conflict', (), {'first': 'arg'}, 'conflict-first/arg/'),
|
||||||
# The number and order of the arguments don't interfere with reversing.
|
('name-conflict', (), {'middle': 'arg'}, 'conflict-middle/arg/'),
|
||||||
self.assertEqual(resolver.reverse('name-conflict', 'arg', 'arg'), 'conflict/arg/arg/')
|
('name-conflict', (), {'last': 'arg'}, 'conflict-last/arg/'),
|
||||||
|
# The number and order of the arguments don't interfere with reversing.
|
||||||
|
('name-conflict', ('arg', 'arg'), {}, 'conflict/arg/arg/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(resolver.reverse(name, *args, **kwargs), expected)
|
||||||
|
|
||||||
def test_non_regex(self):
|
def test_non_regex(self):
|
||||||
"""
|
"""
|
||||||
|
@ -410,14 +423,11 @@ class ResolverTests(SimpleTestCase):
|
||||||
the root pattern '^/'. Never return None from resolve() to prevent a
|
the root pattern '^/'. Never return None from resolve() to prevent a
|
||||||
TypeError from occurring later (#10834).
|
TypeError from occurring later (#10834).
|
||||||
"""
|
"""
|
||||||
with self.assertRaises(Resolver404):
|
test_urls = ['', 'a', '\\', '.']
|
||||||
resolve('')
|
for path in test_urls:
|
||||||
with self.assertRaises(Resolver404):
|
with self.subTest(path=path):
|
||||||
resolve('a')
|
with self.assertRaises(Resolver404):
|
||||||
with self.assertRaises(Resolver404):
|
resolve(path)
|
||||||
resolve('\\')
|
|
||||||
with self.assertRaises(Resolver404):
|
|
||||||
resolve('.')
|
|
||||||
|
|
||||||
def test_404_tried_urls_have_names(self):
|
def test_404_tried_urls_have_names(self):
|
||||||
"""
|
"""
|
||||||
|
@ -452,16 +462,17 @@ class ResolverTests(SimpleTestCase):
|
||||||
)
|
)
|
||||||
for tried, expected in zip(e.args[0]['tried'], url_types_names):
|
for tried, expected in zip(e.args[0]['tried'], url_types_names):
|
||||||
for t, e in zip(tried, expected):
|
for t, e in zip(tried, expected):
|
||||||
self.assertIsInstance(t, e['type']), '%s is not an instance of %s' % (t, e['type'])
|
with self.subTest(t):
|
||||||
if 'name' in e:
|
self.assertIsInstance(t, e['type']), '%s is not an instance of %s' % (t, e['type'])
|
||||||
if not e['name']:
|
if 'name' in e:
|
||||||
self.assertIsNone(t.name, 'Expected no URL name but found %s.' % t.name)
|
if not e['name']:
|
||||||
else:
|
self.assertIsNone(t.name, 'Expected no URL name but found %s.' % t.name)
|
||||||
self.assertEqual(
|
else:
|
||||||
t.name,
|
self.assertEqual(
|
||||||
e['name'],
|
t.name,
|
||||||
'Wrong URL name. Expected "%s", got "%s".' % (e['name'], t.name)
|
e['name'],
|
||||||
)
|
'Wrong URL name. Expected "%s", got "%s".' % (e['name'], t.name)
|
||||||
|
)
|
||||||
|
|
||||||
def test_namespaced_view_detail(self):
|
def test_namespaced_view_detail(self):
|
||||||
resolver = get_resolver('urlpatterns_reverse.nested_urls')
|
resolver = get_resolver('urlpatterns_reverse.nested_urls')
|
||||||
|
@ -593,249 +604,323 @@ class ReverseShortcutTests(SimpleTestCase):
|
||||||
class NamespaceTests(SimpleTestCase):
|
class NamespaceTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_ambiguous_object(self):
|
def test_ambiguous_object(self):
|
||||||
"Names deployed via dynamic URL objects that require namespaces can't be resolved"
|
"""
|
||||||
with self.assertRaises(NoReverseMatch):
|
Names deployed via dynamic URL objects that require namespaces can't
|
||||||
reverse('urlobject-view')
|
be resolved.
|
||||||
with self.assertRaises(NoReverseMatch):
|
"""
|
||||||
reverse('urlobject-view', args=[37, 42])
|
test_urls = [
|
||||||
with self.assertRaises(NoReverseMatch):
|
('urlobject-view', [], {}),
|
||||||
reverse('urlobject-view', kwargs={'arg1': 42, 'arg2': 37})
|
('urlobject-view', [37, 42], {}),
|
||||||
|
('urlobject-view', [], {'arg1': 42, 'arg2': 37}),
|
||||||
|
]
|
||||||
|
for name, args, kwargs in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
with self.assertRaises(NoReverseMatch):
|
||||||
|
reverse(name, args=args, kwargs=kwargs)
|
||||||
|
|
||||||
def test_ambiguous_urlpattern(self):
|
def test_ambiguous_urlpattern(self):
|
||||||
"Names deployed via dynamic URL objects that require namespaces can't be resolved"
|
"""
|
||||||
with self.assertRaises(NoReverseMatch):
|
Names deployed via dynamic URL objects that require namespaces can't
|
||||||
reverse('inner-nothing')
|
be resolved.
|
||||||
with self.assertRaises(NoReverseMatch):
|
"""
|
||||||
reverse('inner-nothing', args=[37, 42])
|
test_urls = [
|
||||||
with self.assertRaises(NoReverseMatch):
|
('inner-nothing', [], {}),
|
||||||
reverse('inner-nothing', kwargs={'arg1': 42, 'arg2': 37})
|
('inner-nothing', [37, 42], {}),
|
||||||
|
('inner-nothing', [], {'arg1': 42, 'arg2': 37}),
|
||||||
|
]
|
||||||
|
for name, args, kwargs in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
with self.assertRaises(NoReverseMatch):
|
||||||
|
reverse(name, args=args, kwargs=kwargs)
|
||||||
|
|
||||||
def test_non_existent_namespace(self):
|
def test_non_existent_namespace(self):
|
||||||
"Nonexistent namespaces raise errors"
|
"""Nonexistent namespaces raise errors."""
|
||||||
with self.assertRaises(NoReverseMatch):
|
test_urls = [
|
||||||
reverse('blahblah:urlobject-view')
|
'blahblah:urlobject-view',
|
||||||
with self.assertRaises(NoReverseMatch):
|
'test-ns1:blahblah:urlobject-view',
|
||||||
reverse('test-ns1:blahblah:urlobject-view')
|
]
|
||||||
|
for name in test_urls:
|
||||||
|
with self.subTest(name=name):
|
||||||
|
with self.assertRaises(NoReverseMatch):
|
||||||
|
reverse(name)
|
||||||
|
|
||||||
def test_normal_name(self):
|
def test_normal_name(self):
|
||||||
"Normal lookups work as expected"
|
"""Normal lookups work as expected."""
|
||||||
self.assertEqual('/normal/', reverse('normal-view'))
|
test_urls = [
|
||||||
self.assertEqual('/normal/37/42/', reverse('normal-view', args=[37, 42]))
|
('normal-view', [], {}, '/normal/'),
|
||||||
self.assertEqual('/normal/42/37/', reverse('normal-view', kwargs={'arg1': 42, 'arg2': 37}))
|
('normal-view', [37, 42], {}, '/normal/37/42/'),
|
||||||
self.assertEqual('/+%5C$*/', reverse('special-view'))
|
('normal-view', [], {'arg1': 42, 'arg2': 37}, '/normal/42/37/'),
|
||||||
|
('special-view', [], {}, '/+%5C$*/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_simple_included_name(self):
|
def test_simple_included_name(self):
|
||||||
"Normal lookups work on names included from other patterns"
|
"""Normal lookups work on names included from other patterns."""
|
||||||
self.assertEqual('/included/normal/', reverse('included_namespace_urls:inc-normal-view'))
|
test_urls = [
|
||||||
self.assertEqual('/included/normal/37/42/', reverse('included_namespace_urls:inc-normal-view', args=[37, 42]))
|
('included_namespace_urls:inc-normal-view', [], {}, '/included/normal/'),
|
||||||
self.assertEqual(
|
('included_namespace_urls:inc-normal-view', [37, 42], {}, '/included/normal/37/42/'),
|
||||||
'/included/normal/42/37/',
|
('included_namespace_urls:inc-normal-view', [], {'arg1': 42, 'arg2': 37}, '/included/normal/42/37/'),
|
||||||
reverse('included_namespace_urls:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37})
|
('included_namespace_urls:inc-special-view', [], {}, '/included/+%5C$*/'),
|
||||||
)
|
]
|
||||||
self.assertEqual('/included/+%5C$*/', reverse('included_namespace_urls:inc-special-view'))
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_namespace_object(self):
|
def test_namespace_object(self):
|
||||||
"Dynamic URL objects can be found using a namespace"
|
"""Dynamic URL objects can be found using a namespace."""
|
||||||
self.assertEqual('/test1/inner/', reverse('test-ns1:urlobject-view'))
|
test_urls = [
|
||||||
self.assertEqual('/test1/inner/37/42/', reverse('test-ns1:urlobject-view', args=[37, 42]))
|
('test-ns1:urlobject-view', [], {}, '/test1/inner/'),
|
||||||
self.assertEqual('/test1/inner/42/37/', reverse('test-ns1:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}))
|
('test-ns1:urlobject-view', [37, 42], {}, '/test1/inner/37/42/'),
|
||||||
self.assertEqual('/test1/inner/+%5C$*/', reverse('test-ns1:urlobject-special-view'))
|
('test-ns1:urlobject-view', [], {'arg1': 42, 'arg2': 37}, '/test1/inner/42/37/'),
|
||||||
|
('test-ns1:urlobject-special-view', [], {}, '/test1/inner/+%5C$*/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_app_object(self):
|
def test_app_object(self):
|
||||||
"Dynamic URL objects can return a (pattern, app_name) 2-tuple, and include() can set the namespace"
|
"""
|
||||||
self.assertEqual('/newapp1/inner/', reverse('new-ns1:urlobject-view'))
|
Dynamic URL objects can return a (pattern, app_name) 2-tuple, and
|
||||||
self.assertEqual('/newapp1/inner/37/42/', reverse('new-ns1:urlobject-view', args=[37, 42]))
|
include() can set the namespace.
|
||||||
self.assertEqual('/newapp1/inner/42/37/', reverse('new-ns1:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}))
|
"""
|
||||||
self.assertEqual('/newapp1/inner/+%5C$*/', reverse('new-ns1:urlobject-special-view'))
|
test_urls = [
|
||||||
|
('new-ns1:urlobject-view', [], {}, '/newapp1/inner/'),
|
||||||
|
('new-ns1:urlobject-view', [37, 42], {}, '/newapp1/inner/37/42/'),
|
||||||
|
('new-ns1:urlobject-view', [], {'arg1': 42, 'arg2': 37}, '/newapp1/inner/42/37/'),
|
||||||
|
('new-ns1:urlobject-special-view', [], {}, '/newapp1/inner/+%5C$*/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_app_object_default_namespace(self):
|
def test_app_object_default_namespace(self):
|
||||||
"Namespace defaults to app_name when including a (pattern, app_name) 2-tuple"
|
"""
|
||||||
self.assertEqual('/new-default/inner/', reverse('newapp:urlobject-view'))
|
Namespace defaults to app_name when including a (pattern, app_name)
|
||||||
self.assertEqual('/new-default/inner/37/42/', reverse('newapp:urlobject-view', args=[37, 42]))
|
2-tuple.
|
||||||
self.assertEqual(
|
"""
|
||||||
'/new-default/inner/42/37/', reverse('newapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37})
|
test_urls = [
|
||||||
)
|
('newapp:urlobject-view', [], {}, '/new-default/inner/'),
|
||||||
self.assertEqual('/new-default/inner/+%5C$*/', reverse('newapp:urlobject-special-view'))
|
('newapp:urlobject-view', [37, 42], {}, '/new-default/inner/37/42/'),
|
||||||
|
('newapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, '/new-default/inner/42/37/'),
|
||||||
|
('newapp:urlobject-special-view', [], {}, '/new-default/inner/+%5C$*/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_embedded_namespace_object(self):
|
def test_embedded_namespace_object(self):
|
||||||
"Namespaces can be installed anywhere in the URL pattern tree"
|
"""Namespaces can be installed anywhere in the URL pattern tree."""
|
||||||
self.assertEqual('/included/test3/inner/', reverse('included_namespace_urls:test-ns3:urlobject-view'))
|
test_urls = [
|
||||||
self.assertEqual(
|
('included_namespace_urls:test-ns3:urlobject-view', [], {}, '/included/test3/inner/'),
|
||||||
'/included/test3/inner/37/42/', reverse('included_namespace_urls:test-ns3:urlobject-view', args=[37, 42])
|
('included_namespace_urls:test-ns3:urlobject-view', [37, 42], {}, '/included/test3/inner/37/42/'),
|
||||||
)
|
(
|
||||||
self.assertEqual(
|
'included_namespace_urls:test-ns3:urlobject-view', [], {'arg1': 42, 'arg2': 37},
|
||||||
'/included/test3/inner/42/37/',
|
'/included/test3/inner/42/37/',
|
||||||
reverse('included_namespace_urls:test-ns3:urlobject-view', kwargs={'arg1': 42, 'arg2': 37})
|
),
|
||||||
)
|
('included_namespace_urls:test-ns3:urlobject-special-view', [], {}, '/included/test3/inner/+%5C$*/'),
|
||||||
self.assertEqual(
|
]
|
||||||
'/included/test3/inner/+%5C$*/', reverse('included_namespace_urls:test-ns3:urlobject-special-view')
|
for name, args, kwargs, expected in test_urls:
|
||||||
)
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_namespace_pattern(self):
|
def test_namespace_pattern(self):
|
||||||
"Namespaces can be applied to include()'d urlpatterns"
|
"""Namespaces can be applied to include()'d urlpatterns."""
|
||||||
self.assertEqual('/ns-included1/normal/', reverse('inc-ns1:inc-normal-view'))
|
test_urls = [
|
||||||
self.assertEqual('/ns-included1/normal/37/42/', reverse('inc-ns1:inc-normal-view', args=[37, 42]))
|
('inc-ns1:inc-normal-view', [], {}, '/ns-included1/normal/'),
|
||||||
self.assertEqual(
|
('inc-ns1:inc-normal-view', [37, 42], {}, '/ns-included1/normal/37/42/'),
|
||||||
'/ns-included1/normal/42/37/', reverse('inc-ns1:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37})
|
('inc-ns1:inc-normal-view', [], {'arg1': 42, 'arg2': 37}, '/ns-included1/normal/42/37/'),
|
||||||
)
|
('inc-ns1:inc-special-view', [], {}, '/ns-included1/+%5C$*/'),
|
||||||
self.assertEqual('/ns-included1/+%5C$*/', reverse('inc-ns1:inc-special-view'))
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_app_name_pattern(self):
|
def test_app_name_pattern(self):
|
||||||
"Namespaces can be applied to include()'d urlpatterns that set an app_name attribute"
|
"""
|
||||||
self.assertEqual('/app-included1/normal/', reverse('app-ns1:inc-normal-view'))
|
Namespaces can be applied to include()'d urlpatterns that set an
|
||||||
self.assertEqual('/app-included1/normal/37/42/', reverse('app-ns1:inc-normal-view', args=[37, 42]))
|
app_name attribute.
|
||||||
self.assertEqual(
|
"""
|
||||||
'/app-included1/normal/42/37/', reverse('app-ns1:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37})
|
test_urls = [
|
||||||
)
|
('app-ns1:inc-normal-view', [], {}, '/app-included1/normal/'),
|
||||||
self.assertEqual('/app-included1/+%5C$*/', reverse('app-ns1:inc-special-view'))
|
('app-ns1:inc-normal-view', [37, 42], {}, '/app-included1/normal/37/42/'),
|
||||||
|
('app-ns1:inc-normal-view', [], {'arg1': 42, 'arg2': 37}, '/app-included1/normal/42/37/'),
|
||||||
|
('app-ns1:inc-special-view', [], {}, '/app-included1/+%5C$*/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_namespace_pattern_with_variable_prefix(self):
|
def test_namespace_pattern_with_variable_prefix(self):
|
||||||
"When using an include with namespaces when there is a regex variable in front of it"
|
"""
|
||||||
self.assertEqual('/ns-outer/42/normal/', reverse('inc-outer:inc-normal-view', kwargs={'outer': 42}))
|
Using include() with namespaces when there is a regex variable in front
|
||||||
self.assertEqual('/ns-outer/42/normal/', reverse('inc-outer:inc-normal-view', args=[42]))
|
of it.
|
||||||
self.assertEqual(
|
"""
|
||||||
'/ns-outer/42/normal/37/4/',
|
test_urls = [
|
||||||
reverse('inc-outer:inc-normal-view', kwargs={'outer': 42, 'arg1': 37, 'arg2': 4})
|
('inc-outer:inc-normal-view', [], {'outer': 42}, '/ns-outer/42/normal/'),
|
||||||
)
|
('inc-outer:inc-normal-view', [42], {}, '/ns-outer/42/normal/'),
|
||||||
self.assertEqual('/ns-outer/42/normal/37/4/', reverse('inc-outer:inc-normal-view', args=[42, 37, 4]))
|
('inc-outer:inc-normal-view', [], {'arg1': 37, 'arg2': 4, 'outer': 42}, '/ns-outer/42/normal/37/4/'),
|
||||||
self.assertEqual('/ns-outer/42/+%5C$*/', reverse('inc-outer:inc-special-view', kwargs={'outer': 42}))
|
('inc-outer:inc-normal-view', [42, 37, 4], {}, '/ns-outer/42/normal/37/4/'),
|
||||||
self.assertEqual('/ns-outer/42/+%5C$*/', reverse('inc-outer:inc-special-view', args=[42]))
|
('inc-outer:inc-special-view', [], {'outer': 42}, '/ns-outer/42/+%5C$*/'),
|
||||||
|
('inc-outer:inc-special-view', [42], {}, '/ns-outer/42/+%5C$*/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_multiple_namespace_pattern(self):
|
def test_multiple_namespace_pattern(self):
|
||||||
"Namespaces can be embedded"
|
"""Namespaces can be embedded."""
|
||||||
self.assertEqual('/ns-included1/test3/inner/', reverse('inc-ns1:test-ns3:urlobject-view'))
|
test_urls = [
|
||||||
self.assertEqual('/ns-included1/test3/inner/37/42/', reverse('inc-ns1:test-ns3:urlobject-view', args=[37, 42]))
|
('inc-ns1:test-ns3:urlobject-view', [], {}, '/ns-included1/test3/inner/'),
|
||||||
self.assertEqual(
|
('inc-ns1:test-ns3:urlobject-view', [37, 42], {}, '/ns-included1/test3/inner/37/42/'),
|
||||||
'/ns-included1/test3/inner/42/37/',
|
(
|
||||||
reverse('inc-ns1:test-ns3:urlobject-view', kwargs={'arg1': 42, 'arg2': 37})
|
'inc-ns1:test-ns3:urlobject-view', [], {'arg1': 42, 'arg2': 37},
|
||||||
)
|
'/ns-included1/test3/inner/42/37/',
|
||||||
self.assertEqual('/ns-included1/test3/inner/+%5C$*/', reverse('inc-ns1:test-ns3:urlobject-special-view'))
|
),
|
||||||
|
('inc-ns1:test-ns3:urlobject-special-view', [], {}, '/ns-included1/test3/inner/+%5C$*/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_nested_namespace_pattern(self):
|
def test_nested_namespace_pattern(self):
|
||||||
"Namespaces can be nested"
|
"""Namespaces can be nested."""
|
||||||
self.assertEqual(
|
test_urls = [
|
||||||
'/ns-included1/ns-included4/ns-included1/test3/inner/',
|
(
|
||||||
reverse('inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view')
|
'inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', [], {},
|
||||||
)
|
'/ns-included1/ns-included4/ns-included1/test3/inner/',
|
||||||
self.assertEqual(
|
),
|
||||||
'/ns-included1/ns-included4/ns-included1/test3/inner/37/42/',
|
(
|
||||||
reverse('inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', args=[37, 42])
|
'inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', [37, 42], {},
|
||||||
)
|
'/ns-included1/ns-included4/ns-included1/test3/inner/37/42/',
|
||||||
self.assertEqual(
|
),
|
||||||
'/ns-included1/ns-included4/ns-included1/test3/inner/42/37/',
|
(
|
||||||
reverse('inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', kwargs={'arg1': 42, 'arg2': 37})
|
'inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-view', [], {'arg1': 42, 'arg2': 37},
|
||||||
)
|
'/ns-included1/ns-included4/ns-included1/test3/inner/42/37/',
|
||||||
self.assertEqual(
|
),
|
||||||
'/ns-included1/ns-included4/ns-included1/test3/inner/+%5C$*/',
|
(
|
||||||
reverse('inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-special-view')
|
'inc-ns1:inc-ns4:inc-ns1:test-ns3:urlobject-special-view', [], {},
|
||||||
)
|
'/ns-included1/ns-included4/ns-included1/test3/inner/+%5C$*/',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_app_lookup_object(self):
|
def test_app_lookup_object(self):
|
||||||
"A default application namespace can be used for lookup"
|
"""A default application namespace can be used for lookup."""
|
||||||
self.assertEqual('/default/inner/', reverse('testapp:urlobject-view'))
|
test_urls = [
|
||||||
self.assertEqual('/default/inner/37/42/', reverse('testapp:urlobject-view', args=[37, 42]))
|
('testapp:urlobject-view', [], {}, '/default/inner/'),
|
||||||
self.assertEqual('/default/inner/42/37/', reverse('testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}))
|
('testapp:urlobject-view', [37, 42], {}, '/default/inner/37/42/'),
|
||||||
self.assertEqual('/default/inner/+%5C$*/', reverse('testapp:urlobject-special-view'))
|
('testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, '/default/inner/42/37/'),
|
||||||
|
('testapp:urlobject-special-view', [], {}, '/default/inner/+%5C$*/'),
|
||||||
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_app_lookup_object_with_default(self):
|
def test_app_lookup_object_with_default(self):
|
||||||
"A default application namespace is sensitive to the 'current' app can be used for lookup"
|
"""A default application namespace is sensitive to the current app."""
|
||||||
self.assertEqual('/default/inner/', reverse('testapp:urlobject-view', current_app='test-ns3'))
|
test_urls = [
|
||||||
self.assertEqual(
|
('testapp:urlobject-view', [], {}, 'test-ns3', '/default/inner/'),
|
||||||
'/default/inner/37/42/',
|
('testapp:urlobject-view', [37, 42], {}, 'test-ns3', '/default/inner/37/42/'),
|
||||||
reverse('testapp:urlobject-view', args=[37, 42], current_app='test-ns3')
|
('testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, 'test-ns3', '/default/inner/42/37/'),
|
||||||
)
|
('testapp:urlobject-special-view', [], {}, 'test-ns3', '/default/inner/+%5C$*/'),
|
||||||
self.assertEqual(
|
]
|
||||||
'/default/inner/42/37/',
|
for name, args, kwargs, current_app, expected in test_urls:
|
||||||
reverse('testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='test-ns3')
|
with self.subTest(name=name, args=args, kwargs=kwargs, current_app=current_app):
|
||||||
)
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs, current_app=current_app), expected)
|
||||||
self.assertEqual(
|
|
||||||
'/default/inner/+%5C$*/', reverse('testapp:urlobject-special-view', current_app='test-ns3')
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_app_lookup_object_without_default(self):
|
def test_app_lookup_object_without_default(self):
|
||||||
"An application namespace without a default is sensitive to the 'current' app can be used for lookup"
|
"""
|
||||||
self.assertEqual('/other2/inner/', reverse('nodefault:urlobject-view'))
|
An application namespace without a default is sensitive to the current
|
||||||
self.assertEqual('/other2/inner/37/42/', reverse('nodefault:urlobject-view', args=[37, 42]))
|
app.
|
||||||
self.assertEqual('/other2/inner/42/37/', reverse('nodefault:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}))
|
"""
|
||||||
self.assertEqual('/other2/inner/+%5C$*/', reverse('nodefault:urlobject-special-view'))
|
test_urls = [
|
||||||
|
('nodefault:urlobject-view', [], {}, None, '/other2/inner/'),
|
||||||
self.assertEqual('/other1/inner/', reverse('nodefault:urlobject-view', current_app='other-ns1'))
|
('nodefault:urlobject-view', [37, 42], {}, None, '/other2/inner/37/42/'),
|
||||||
self.assertEqual(
|
('nodefault:urlobject-view', [], {'arg1': 42, 'arg2': 37}, None, '/other2/inner/42/37/'),
|
||||||
'/other1/inner/37/42/', reverse('nodefault:urlobject-view', args=[37, 42], current_app='other-ns1')
|
('nodefault:urlobject-special-view', [], {}, None, '/other2/inner/+%5C$*/'),
|
||||||
)
|
('nodefault:urlobject-view', [], {}, 'other-ns1', '/other1/inner/'),
|
||||||
self.assertEqual(
|
('nodefault:urlobject-view', [37, 42], {}, 'other-ns1', '/other1/inner/37/42/'),
|
||||||
'/other1/inner/42/37/',
|
('nodefault:urlobject-view', [], {'arg1': 42, 'arg2': 37}, 'other-ns1', '/other1/inner/42/37/'),
|
||||||
reverse('nodefault:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='other-ns1')
|
('nodefault:urlobject-special-view', [], {}, 'other-ns1', '/other1/inner/+%5C$*/'),
|
||||||
)
|
]
|
||||||
self.assertEqual('/other1/inner/+%5C$*/', reverse('nodefault:urlobject-special-view', current_app='other-ns1'))
|
for name, args, kwargs, current_app, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs, current_app=current_app):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs, current_app=current_app), expected)
|
||||||
|
|
||||||
def test_special_chars_namespace(self):
|
def test_special_chars_namespace(self):
|
||||||
self.assertEqual('/+%5C$*/included/normal/', reverse('special:included_namespace_urls:inc-normal-view'))
|
test_urls = [
|
||||||
self.assertEqual(
|
('special:included_namespace_urls:inc-normal-view', [], {}, '/+%5C$*/included/normal/'),
|
||||||
'/+%5C$*/included/normal/37/42/',
|
('special:included_namespace_urls:inc-normal-view', [37, 42], {}, '/+%5C$*/included/normal/37/42/'),
|
||||||
reverse('special:included_namespace_urls:inc-normal-view', args=[37, 42])
|
(
|
||||||
)
|
'special:included_namespace_urls:inc-normal-view', [], {'arg1': 42, 'arg2': 37},
|
||||||
self.assertEqual(
|
'/+%5C$*/included/normal/42/37/',
|
||||||
'/+%5C$*/included/normal/42/37/',
|
),
|
||||||
reverse('special:included_namespace_urls:inc-normal-view', kwargs={'arg1': 42, 'arg2': 37})
|
('special:included_namespace_urls:inc-special-view', [], {}, '/+%5C$*/included/+%5C$*/'),
|
||||||
)
|
]
|
||||||
self.assertEqual('/+%5C$*/included/+%5C$*/', reverse('special:included_namespace_urls:inc-special-view'))
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_namespaces_with_variables(self):
|
def test_namespaces_with_variables(self):
|
||||||
"Namespace prefixes can capture variables: see #15900"
|
"""Namespace prefixes can capture variables."""
|
||||||
self.assertEqual('/inc70/', reverse('inc-ns5:inner-nothing', kwargs={'outer': '70'}))
|
test_urls = [
|
||||||
self.assertEqual(
|
('inc-ns5:inner-nothing', [], {'outer': '70'}, '/inc70/'),
|
||||||
'/inc78/extra/foobar/', reverse('inc-ns5:inner-extra', kwargs={'outer': '78', 'extra': 'foobar'})
|
('inc-ns5:inner-extra', [], {'extra': 'foobar', 'outer': '78'}, '/inc78/extra/foobar/'),
|
||||||
)
|
('inc-ns5:inner-nothing', ['70'], {}, '/inc70/'),
|
||||||
self.assertEqual('/inc70/', reverse('inc-ns5:inner-nothing', args=['70']))
|
('inc-ns5:inner-extra', ['78', 'foobar'], {}, '/inc78/extra/foobar/'),
|
||||||
self.assertEqual('/inc78/extra/foobar/', reverse('inc-ns5:inner-extra', args=['78', 'foobar']))
|
]
|
||||||
|
for name, args, kwargs, expected in test_urls:
|
||||||
|
with self.subTest(name=name, args=args, kwargs=kwargs):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_nested_app_lookup(self):
|
def test_nested_app_lookup(self):
|
||||||
"A nested current_app should be split in individual namespaces (#24904)"
|
"""
|
||||||
self.assertEqual('/ns-included1/test4/inner/', reverse('inc-ns1:testapp:urlobject-view'))
|
A nested current_app should be split in individual namespaces (#24904).
|
||||||
self.assertEqual('/ns-included1/test4/inner/37/42/', reverse('inc-ns1:testapp:urlobject-view', args=[37, 42]))
|
"""
|
||||||
self.assertEqual(
|
test_urls = [
|
||||||
'/ns-included1/test4/inner/42/37/',
|
('inc-ns1:testapp:urlobject-view', [], {}, None, '/ns-included1/test4/inner/'),
|
||||||
reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37})
|
('inc-ns1:testapp:urlobject-view', [37, 42], {}, None, '/ns-included1/test4/inner/37/42/'),
|
||||||
)
|
('inc-ns1:testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, None, '/ns-included1/test4/inner/42/37/'),
|
||||||
self.assertEqual('/ns-included1/test4/inner/+%5C$*/', reverse('inc-ns1:testapp:urlobject-special-view'))
|
('inc-ns1:testapp:urlobject-special-view', [], {}, None, '/ns-included1/test4/inner/+%5C$*/'),
|
||||||
|
('inc-ns1:testapp:urlobject-view', [], {}, 'inc-ns1:test-ns3', '/ns-included1/test3/inner/'),
|
||||||
self.assertEqual(
|
('inc-ns1:testapp:urlobject-view', [37, 42], {}, 'inc-ns1:test-ns3', '/ns-included1/test3/inner/37/42/'),
|
||||||
'/ns-included1/test3/inner/',
|
(
|
||||||
reverse('inc-ns1:testapp:urlobject-view', current_app='inc-ns1:test-ns3')
|
'inc-ns1:testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, 'inc-ns1:test-ns3',
|
||||||
)
|
'/ns-included1/test3/inner/42/37/',
|
||||||
self.assertEqual(
|
),
|
||||||
'/ns-included1/test3/inner/37/42/',
|
(
|
||||||
reverse('inc-ns1:testapp:urlobject-view', args=[37, 42], current_app='inc-ns1:test-ns3')
|
'inc-ns1:testapp:urlobject-special-view', [], {}, 'inc-ns1:test-ns3',
|
||||||
)
|
'/ns-included1/test3/inner/+%5C$*/',
|
||||||
self.assertEqual(
|
),
|
||||||
'/ns-included1/test3/inner/42/37/',
|
]
|
||||||
reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='inc-ns1:test-ns3')
|
for name, args, kwargs, current_app, expected in test_urls:
|
||||||
)
|
with self.subTest(name=name, args=args, kwargs=kwargs, current_app=current_app):
|
||||||
self.assertEqual(
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs, current_app=current_app), expected)
|
||||||
'/ns-included1/test3/inner/+%5C$*/',
|
|
||||||
reverse('inc-ns1:testapp:urlobject-special-view', current_app='inc-ns1:test-ns3')
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_current_app_no_partial_match(self):
|
def test_current_app_no_partial_match(self):
|
||||||
"current_app should either match the whole path or shouldn't be used"
|
"""current_app shouldn't be used unless it matches the whole path."""
|
||||||
self.assertEqual(
|
test_urls = [
|
||||||
'/ns-included1/test4/inner/',
|
('inc-ns1:testapp:urlobject-view', [], {}, 'nonexistent:test-ns3', '/ns-included1/test4/inner/'),
|
||||||
reverse('inc-ns1:testapp:urlobject-view', current_app='nonexistent:test-ns3')
|
(
|
||||||
)
|
'inc-ns1:testapp:urlobject-view', [37, 42], {}, 'nonexistent:test-ns3',
|
||||||
self.assertEqual(
|
'/ns-included1/test4/inner/37/42/',
|
||||||
'/ns-included1/test4/inner/37/42/',
|
),
|
||||||
reverse('inc-ns1:testapp:urlobject-view', args=[37, 42], current_app='nonexistent:test-ns3')
|
(
|
||||||
)
|
'inc-ns1:testapp:urlobject-view', [], {'arg1': 42, 'arg2': 37}, 'nonexistent:test-ns3',
|
||||||
self.assertEqual(
|
'/ns-included1/test4/inner/42/37/',
|
||||||
'/ns-included1/test4/inner/42/37/',
|
),
|
||||||
reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37},
|
(
|
||||||
current_app='nonexistent:test-ns3')
|
'inc-ns1:testapp:urlobject-special-view', [], {}, 'nonexistent:test-ns3',
|
||||||
)
|
'/ns-included1/test4/inner/+%5C$*/',
|
||||||
self.assertEqual(
|
),
|
||||||
'/ns-included1/test4/inner/+%5C$*/',
|
]
|
||||||
reverse('inc-ns1:testapp:urlobject-special-view', current_app='nonexistent:test-ns3')
|
for name, args, kwargs, current_app, expected in test_urls:
|
||||||
)
|
with self.subTest(name=name, args=args, kwargs=kwargs, current_app=current_app):
|
||||||
|
self.assertEqual(reverse(name, args=args, kwargs=kwargs, current_app=current_app), expected)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF=urlconf_outer.__name__)
|
@override_settings(ROOT_URLCONF=urlconf_outer.__name__)
|
||||||
|
@ -954,15 +1039,15 @@ class ErrorHandlerResolutionTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_named_handlers(self):
|
def test_named_handlers(self):
|
||||||
handler = (empty_view, {})
|
handler = (empty_view, {})
|
||||||
self.assertEqual(self.resolver.resolve_error_handler(400), handler)
|
for code in [400, 404, 500]:
|
||||||
self.assertEqual(self.resolver.resolve_error_handler(404), handler)
|
with self.subTest(code=code):
|
||||||
self.assertEqual(self.resolver.resolve_error_handler(500), handler)
|
self.assertEqual(self.resolver.resolve_error_handler(code), handler)
|
||||||
|
|
||||||
def test_callable_handlers(self):
|
def test_callable_handlers(self):
|
||||||
handler = (empty_view, {})
|
handler = (empty_view, {})
|
||||||
self.assertEqual(self.callable_resolver.resolve_error_handler(400), handler)
|
for code in [400, 404, 500]:
|
||||||
self.assertEqual(self.callable_resolver.resolve_error_handler(404), handler)
|
with self.subTest(code=code):
|
||||||
self.assertEqual(self.callable_resolver.resolve_error_handler(500), handler)
|
self.assertEqual(self.callable_resolver.resolve_error_handler(code), handler)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='urlpatterns_reverse.urls_without_full_import')
|
@override_settings(ROOT_URLCONF='urlpatterns_reverse.urls_without_full_import')
|
||||||
|
@ -991,27 +1076,26 @@ class ResolverMatchTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_urlpattern_resolve(self):
|
def test_urlpattern_resolve(self):
|
||||||
for path, url_name, app_name, namespace, view_name, func, args, kwargs in resolve_test_data:
|
for path, url_name, app_name, namespace, view_name, func, args, kwargs in resolve_test_data:
|
||||||
# Test legacy support for extracting "function, args, kwargs"
|
with self.subTest(path=path):
|
||||||
match_func, match_args, match_kwargs = resolve(path)
|
# Legacy support for extracting "function, args, kwargs".
|
||||||
self.assertEqual(match_func, func)
|
match_func, match_args, match_kwargs = resolve(path)
|
||||||
self.assertEqual(match_args, args)
|
self.assertEqual(match_func, func)
|
||||||
self.assertEqual(match_kwargs, kwargs)
|
self.assertEqual(match_args, args)
|
||||||
|
self.assertEqual(match_kwargs, kwargs)
|
||||||
# Test ResolverMatch capabilities.
|
# ResolverMatch capabilities.
|
||||||
match = resolve(path)
|
match = resolve(path)
|
||||||
self.assertEqual(match.__class__, ResolverMatch)
|
self.assertEqual(match.__class__, ResolverMatch)
|
||||||
self.assertEqual(match.url_name, url_name)
|
self.assertEqual(match.url_name, url_name)
|
||||||
self.assertEqual(match.app_name, app_name)
|
self.assertEqual(match.app_name, app_name)
|
||||||
self.assertEqual(match.namespace, namespace)
|
self.assertEqual(match.namespace, namespace)
|
||||||
self.assertEqual(match.view_name, view_name)
|
self.assertEqual(match.view_name, view_name)
|
||||||
self.assertEqual(match.func, func)
|
self.assertEqual(match.func, func)
|
||||||
self.assertEqual(match.args, args)
|
self.assertEqual(match.args, args)
|
||||||
self.assertEqual(match.kwargs, kwargs)
|
self.assertEqual(match.kwargs, kwargs)
|
||||||
|
# and for legacy purposes:
|
||||||
# ... and for legacy purposes:
|
self.assertEqual(match[0], func)
|
||||||
self.assertEqual(match[0], func)
|
self.assertEqual(match[1], args)
|
||||||
self.assertEqual(match[1], args)
|
self.assertEqual(match[2], kwargs)
|
||||||
self.assertEqual(match[2], kwargs)
|
|
||||||
|
|
||||||
def test_resolver_match_on_request(self):
|
def test_resolver_match_on_request(self):
|
||||||
response = self.client.get('/resolver_match/')
|
response = self.client.get('/resolver_match/')
|
||||||
|
@ -1125,8 +1209,8 @@ class LookaheadTests(SimpleTestCase):
|
||||||
'/lookbehind+/a-city/',
|
'/lookbehind+/a-city/',
|
||||||
]
|
]
|
||||||
for test_url in test_urls:
|
for test_url in test_urls:
|
||||||
match = resolve(test_url)
|
with self.subTest(url=test_url):
|
||||||
self.assertEqual(match.kwargs, {'city': 'a-city'})
|
self.assertEqual(resolve(test_url).kwargs, {'city': 'a-city'})
|
||||||
|
|
||||||
def test_invalid_resolve(self):
|
def test_invalid_resolve(self):
|
||||||
test_urls = [
|
test_urls = [
|
||||||
|
@ -1136,27 +1220,29 @@ class LookaheadTests(SimpleTestCase):
|
||||||
'/lookbehind+/other-city/',
|
'/lookbehind+/other-city/',
|
||||||
]
|
]
|
||||||
for test_url in test_urls:
|
for test_url in test_urls:
|
||||||
with self.assertRaises(Resolver404):
|
with self.subTest(url=test_url):
|
||||||
resolve(test_url)
|
with self.assertRaises(Resolver404):
|
||||||
|
resolve(test_url)
|
||||||
|
|
||||||
def test_valid_reverse(self):
|
def test_valid_reverse(self):
|
||||||
url = reverse('lookahead-positive', kwargs={'city': 'a-city'})
|
test_urls = [
|
||||||
self.assertEqual(url, '/lookahead+/a-city/')
|
('lookahead-positive', {'city': 'a-city'}, '/lookahead+/a-city/'),
|
||||||
url = reverse('lookahead-negative', kwargs={'city': 'a-city'})
|
('lookahead-negative', {'city': 'a-city'}, '/lookahead-/a-city/'),
|
||||||
self.assertEqual(url, '/lookahead-/a-city/')
|
('lookbehind-positive', {'city': 'a-city'}, '/lookbehind+/a-city/'),
|
||||||
|
('lookbehind-negative', {'city': 'a-city'}, '/lookbehind-/a-city/'),
|
||||||
url = reverse('lookbehind-positive', kwargs={'city': 'a-city'})
|
]
|
||||||
self.assertEqual(url, '/lookbehind+/a-city/')
|
for name, kwargs, expected in test_urls:
|
||||||
url = reverse('lookbehind-negative', kwargs={'city': 'a-city'})
|
with self.subTest(name=name, kwargs=kwargs):
|
||||||
self.assertEqual(url, '/lookbehind-/a-city/')
|
self.assertEqual(reverse(name, kwargs=kwargs), expected)
|
||||||
|
|
||||||
def test_invalid_reverse(self):
|
def test_invalid_reverse(self):
|
||||||
with self.assertRaises(NoReverseMatch):
|
test_urls = [
|
||||||
reverse('lookahead-positive', kwargs={'city': 'other-city'})
|
('lookahead-positive', {'city': 'other-city'}),
|
||||||
with self.assertRaises(NoReverseMatch):
|
('lookahead-negative', {'city': 'not-a-city'}),
|
||||||
reverse('lookahead-negative', kwargs={'city': 'not-a-city'})
|
('lookbehind-positive', {'city': 'other-city'}),
|
||||||
|
('lookbehind-negative', {'city': 'not-a-city'}),
|
||||||
with self.assertRaises(NoReverseMatch):
|
]
|
||||||
reverse('lookbehind-positive', kwargs={'city': 'other-city'})
|
for name, kwargs in test_urls:
|
||||||
with self.assertRaises(NoReverseMatch):
|
with self.subTest(name=name, kwargs=kwargs):
|
||||||
reverse('lookbehind-negative', kwargs={'city': 'not-a-city'})
|
with self.assertRaises(NoReverseMatch):
|
||||||
|
reverse(name, kwargs=kwargs)
|
||||||
|
|
Loading…
Reference in New Issue