Michael Merickel
2018-10-15 3670c2cdb732d378ba6d38e72e7cd875ff726aa9
commit | author | age
f52759 1 # -*- coding: utf-8 -*-
8b2c67 2 import unittest
CM 3
b60bdb 4 from pyramid.testing import cleanUp
118ea0 5
92dcb5 6 from pyramid.compat import (
CM 7     text_,
8     native_,
9     text_type,
10     url_quote,
bc37a5 11     PY2,
92dcb5 12     )
8f8869 13
e6e0ea 14 class TraversalPathTests(unittest.TestCase):
eb6afe 15     def _callFUT(self, path):
b60bdb 16         from pyramid.traversal import traversal_path
e6e0ea 17         return traversal_path(path)
51c305 18
f84147 19     def test_utf8(self):
CM 20         la = b'La Pe\xc3\xb1a'
21         encoded = url_quote(la)
22         decoded = text_(la, 'utf-8')
23         path = '/'.join([encoded, encoded])
24         result = self._callFUT(path)
25         self.assertEqual(result, (decoded, decoded))
26
27     def test_utf16(self):
28         from pyramid.exceptions import URLDecodeError
29         la = text_(b'La Pe\xc3\xb1a', 'utf-8').encode('utf-16')
30         encoded = url_quote(la)
31         path = '/'.join([encoded, encoded])
32         self.assertRaises(URLDecodeError, self._callFUT, path)
33
34     def test_unicode_highorder_chars(self):
35         path = text_('/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF')
36         self.assertEqual(self._callFUT(path),
37                          (text_('\u6d41\u884c\u8d8b\u52bf', 'unicode_escape'),))
38
39     def test_element_urllquoted(self):
40         self.assertEqual(self._callFUT('/foo/space%20thing/bar'),
41                          (text_('foo'), text_('space thing'), text_('bar')))
42
43     def test_unicode_undecodeable_to_ascii(self):
44         path = text_(b'/La Pe\xc3\xb1a', 'utf-8')
45         self.assertRaises(UnicodeEncodeError, self._callFUT, path)
46
47 class TraversalPathInfoTests(unittest.TestCase):
48     def _callFUT(self, path):
49         from pyramid.traversal import traversal_path_info
50         return traversal_path_info(path)
51
dc16fa 52     def test_path_startswith_endswith(self):
e6c2d2 53         self.assertEqual(self._callFUT('/foo/'), (text_('foo'),))
8b2c67 54
dc16fa 55     def test_empty_elements(self):
e6c2d2 56         self.assertEqual(self._callFUT('foo///'), (text_('foo'),))
8b2c67 57
dc16fa 58     def test_onedot(self):
e6c2d2 59         self.assertEqual(self._callFUT('foo/./bar'),
CM 60                          (text_('foo'), text_('bar')))
8b2c67 61
dc16fa 62     def test_twodots(self):
e6c2d2 63         self.assertEqual(self._callFUT('foo/../bar'), (text_('bar'),))
8b2c67 64
f2ef79 65     def test_twodots_at_start(self):
e6c2d2 66         self.assertEqual(self._callFUT('../../bar'), (text_('bar'),))
f2ef79 67
dc16fa 68     def test_segments_are_unicode(self):
CM 69         result = self._callFUT('/foo/bar')
8e606d 70         self.assertEqual(type(result[0]), text_type)
CM 71         self.assertEqual(type(result[1]), text_type)
e281fa 72
CM 73     def test_same_value_returned_if_cached(self):
74         result1 = self._callFUT('/foo/bar')
75         result2 = self._callFUT('/foo/bar')
e6c2d2 76         self.assertEqual(result1, (text_('foo'), text_('bar')))
CM 77         self.assertEqual(result2, (text_('foo'), text_('bar')))
dc16fa 78
841313 79     def test_unicode_simple(self):
e6c2d2 80         path = text_('/abc')
CM 81         self.assertEqual(self._callFUT(path), (text_('abc'),))
841313 82
f84147 83     def test_highorder(self):
CM 84         la = b'La Pe\xc3\xb1a'
85         latin1 = native_(la)
86         result = self._callFUT(latin1)
87         self.assertEqual(result, (text_(la, 'utf-8'),))
88
89     def test_highorder_undecodeable(self):
90         from pyramid.exceptions import URLDecodeError
91         la = text_(b'La Pe\xc3\xb1a', 'utf-8')
92         notlatin1 = native_(la)
93         self.assertRaises(URLDecodeError, self._callFUT, notlatin1)
841313 94
92c3e5 95 class ResourceTreeTraverserTests(unittest.TestCase):
8f8869 96     def setUp(self):
ed2d14 97         cleanUp()
8f8869 98
CM 99     def tearDown(self):
ed2d14 100         cleanUp()
916f88 101
8b2c67 102     def _getTargetClass(self):
92c3e5 103         from pyramid.traversal import ResourceTreeTraverser
CM 104         return ResourceTreeTraverser
8b2c67 105
CM 106     def _makeOne(self, *arg, **kw):
107         klass = self._getTargetClass()
108         return klass(*arg, **kw)
109
281a7a 110     def _getEnviron(self, **kw):
CM 111         environ = {}
112         environ.update(kw)
113         return environ
114
8392d7 115     def test_class_conforms_to_ITraverser(self):
8b2c67 116         from zope.interface.verify import verifyClass
b60bdb 117         from pyramid.interfaces import ITraverser
4df575 118         verifyClass(ITraverser, self._getTargetClass())
8b2c67 119
8392d7 120     def test_instance_conforms_to_ITraverser(self):
8b2c67 121         from zope.interface.verify import verifyObject
b60bdb 122         from pyramid.interfaces import ITraverser
7de404 123         context = DummyContext()
cc5e49 124         verifyObject(ITraverser, self._makeOne(context))
8b2c67 125
27d874 126     def test_call_with_empty_pathinfo(self):
de4969 127         policy = self._makeOne(None)
CM 128         environ = self._getEnviron()
27d874 129         request = DummyRequest(environ, path_info='')
CM 130         result = policy(request)
131         self.assertEqual(result['context'], None)
132         self.assertEqual(result['view_name'], '')
133         self.assertEqual(result['subpath'], ())
134         self.assertEqual(result['traversed'], ())
135         self.assertEqual(result['root'], policy.root)
136         self.assertEqual(result['virtual_root'], policy.root)
137         self.assertEqual(result['virtual_root_path'], ())
138
139     def test_call_with_pathinfo_KeyError(self):
140         policy = self._makeOne(None)
141         environ = self._getEnviron()
142         request = DummyRequest(environ, toraise=KeyError)
f426e5 143         result = policy(request)
916f88 144         self.assertEqual(result['context'], None)
CM 145         self.assertEqual(result['view_name'], '')
6ecdbc 146         self.assertEqual(result['subpath'], ())
1cd598 147         self.assertEqual(result['traversed'], ())
92dcb5 148         self.assertEqual(result['root'], policy.root)
CM 149         self.assertEqual(result['virtual_root'], policy.root)
150         self.assertEqual(result['virtual_root_path'], ())
151
152     def test_call_with_pathinfo_highorder(self):
def68d 153         path = text_(b'/Qu\xc3\xa9bec', 'utf-8')
CM 154         foo = DummyContext(None, path)
92dcb5 155         root = DummyContext(foo, 'root')
CM 156         policy = self._makeOne(root)
def68d 157         environ = self._getEnviron()
CM 158         request = DummyRequest(environ, path_info=path)
92dcb5 159         result = policy(request)
CM 160         self.assertEqual(result['context'], foo)
161         self.assertEqual(result['view_name'], '')
162         self.assertEqual(result['subpath'], ())
def68d 163         self.assertEqual(result['traversed'], (path[1:],))
7fc6a3 164         self.assertEqual(result['root'], policy.root)
916f88 165         self.assertEqual(result['virtual_root'], policy.root)
1cd598 166         self.assertEqual(result['virtual_root_path'], ())
de4969 167
7de404 168     def test_call_pathel_with_no_getitem(self):
cc5e49 169         policy = self._makeOne(None)
def68d 170         environ = self._getEnviron()
ebcdc7 171         request = DummyRequest(environ, path_info=text_('/foo/bar'))
f426e5 172         result = policy(request)
916f88 173         self.assertEqual(result['context'], None)
CM 174         self.assertEqual(result['view_name'], 'foo')
6ecdbc 175         self.assertEqual(result['subpath'], ('bar',))
1cd598 176         self.assertEqual(result['traversed'], ())
7fc6a3 177         self.assertEqual(result['root'], policy.root)
916f88 178         self.assertEqual(result['virtual_root'], policy.root)
1cd598 179         self.assertEqual(result['virtual_root_path'], ())
8b2c67 180
CM 181     def test_call_withconn_getitem_emptypath_nosubpath(self):
7de404 182         root = DummyContext()
cc5e49 183         policy = self._makeOne(root)
def68d 184         environ = self._getEnviron()
ebcdc7 185         request = DummyRequest(environ, path_info=text_(''))
f426e5 186         result = policy(request)
916f88 187         self.assertEqual(result['context'], root)
CM 188         self.assertEqual(result['view_name'], '')
6ecdbc 189         self.assertEqual(result['subpath'], ())
1cd598 190         self.assertEqual(result['traversed'], ())
7fc6a3 191         self.assertEqual(result['root'], root)
916f88 192         self.assertEqual(result['virtual_root'], root)
1cd598 193         self.assertEqual(result['virtual_root_path'], ())
8b2c67 194
CM 195     def test_call_withconn_getitem_withpath_nosubpath(self):
7de404 196         foo = DummyContext()
CM 197         root = DummyContext(foo)
cc5e49 198         policy = self._makeOne(root)
def68d 199         environ = self._getEnviron()
ebcdc7 200         request = DummyRequest(environ, path_info=text_('/foo/bar'))
f426e5 201         result = policy(request)
916f88 202         self.assertEqual(result['context'], foo)
CM 203         self.assertEqual(result['view_name'], 'bar')
6ecdbc 204         self.assertEqual(result['subpath'], ())
e6c2d2 205         self.assertEqual(result['traversed'], (text_('foo'),))
7fc6a3 206         self.assertEqual(result['root'], root)
916f88 207         self.assertEqual(result['virtual_root'], root)
1cd598 208         self.assertEqual(result['virtual_root_path'], ())
8b2c67 209
CM 210     def test_call_withconn_getitem_withpath_withsubpath(self):
7de404 211         foo = DummyContext()
CM 212         root = DummyContext(foo)
cc5e49 213         policy = self._makeOne(root)
def68d 214         environ = self._getEnviron()
ebcdc7 215         request = DummyRequest(environ, path_info=text_('/foo/bar/baz/buz'))
f426e5 216         result = policy(request)
916f88 217         self.assertEqual(result['context'], foo)
CM 218         self.assertEqual(result['view_name'], 'bar')
6ecdbc 219         self.assertEqual(result['subpath'], ('baz', 'buz'))
e6c2d2 220         self.assertEqual(result['traversed'], (text_('foo'),))
7fc6a3 221         self.assertEqual(result['root'], root)
916f88 222         self.assertEqual(result['virtual_root'], root)
1cd598 223         self.assertEqual(result['virtual_root_path'], ())
8b2c67 224
8823e2 225     def test_call_with_explicit_viewname(self):
CM 226         foo = DummyContext()
227         root = DummyContext(foo)
cc5e49 228         policy = self._makeOne(root)
def68d 229         environ = self._getEnviron()
ebcdc7 230         request = DummyRequest(environ, path_info=text_('/@@foo'))
f426e5 231         result = policy(request)
916f88 232         self.assertEqual(result['context'], root)
CM 233         self.assertEqual(result['view_name'], 'foo')
6ecdbc 234         self.assertEqual(result['subpath'], ())
1cd598 235         self.assertEqual(result['traversed'], ())
7fc6a3 236         self.assertEqual(result['root'], root)
916f88 237         self.assertEqual(result['virtual_root'], root)
1cd598 238         self.assertEqual(result['virtual_root_path'], ())
8823e2 239
65f3f8 240     def test_call_with_vh_root(self):
def68d 241         environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar')
7fc6a3 242         baz = DummyContext(None, 'baz')
CM 243         bar = DummyContext(baz, 'bar')
244         foo = DummyContext(bar, 'foo')
245         root = DummyContext(foo, 'root')
65f3f8 246         policy = self._makeOne(root)
ebcdc7 247         request = DummyRequest(environ, path_info=text_('/baz'))
f426e5 248         result = policy(request)
916f88 249         self.assertEqual(result['context'], baz)
CM 250         self.assertEqual(result['view_name'], '')
6ecdbc 251         self.assertEqual(result['subpath'], ())
e6c2d2 252         self.assertEqual(result['traversed'],
CM 253                          (text_('foo'), text_('bar'), text_('baz')))
7fc6a3 254         self.assertEqual(result['root'], root)
916f88 255         self.assertEqual(result['virtual_root'], bar)
e6c2d2 256         self.assertEqual(result['virtual_root_path'],
CM 257                          (text_('foo'), text_('bar')))
1cd598 258
CM 259     def test_call_with_vh_root2(self):
def68d 260         environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo')
7fc6a3 261         baz = DummyContext(None, 'baz')
CM 262         bar = DummyContext(baz, 'bar')
263         foo = DummyContext(bar, 'foo')
264         root = DummyContext(foo, 'root')
1cd598 265         policy = self._makeOne(root)
ebcdc7 266         request = DummyRequest(environ, path_info=text_('/bar/baz'))
f426e5 267         result = policy(request)
1cd598 268         self.assertEqual(result['context'], baz)
CM 269         self.assertEqual(result['view_name'], '')
270         self.assertEqual(result['subpath'], ())
e6c2d2 271         self.assertEqual(result['traversed'],
CM 272                          (text_('foo'), text_('bar'), text_('baz')))
7fc6a3 273         self.assertEqual(result['root'], root)
1cd598 274         self.assertEqual(result['virtual_root'], foo)
e6c2d2 275         self.assertEqual(result['virtual_root_path'], (text_('foo'),))
1cd598 276
CM 277     def test_call_with_vh_root3(self):
def68d 278         environ = self._getEnviron(HTTP_X_VHM_ROOT='/')
1cd598 279         baz = DummyContext()
CM 280         bar = DummyContext(baz)
281         foo = DummyContext(bar)
282         root = DummyContext(foo)
283         policy = self._makeOne(root)
ebcdc7 284         request = DummyRequest(environ, path_info=text_('/foo/bar/baz'))
f426e5 285         result = policy(request)
1cd598 286         self.assertEqual(result['context'], baz)
CM 287         self.assertEqual(result['view_name'], '')
288         self.assertEqual(result['subpath'], ())
e6c2d2 289         self.assertEqual(result['traversed'],
CM 290                          (text_('foo'), text_('bar'), text_('baz')))
7fc6a3 291         self.assertEqual(result['root'], root)
1cd598 292         self.assertEqual(result['virtual_root'], root)
CM 293         self.assertEqual(result['virtual_root_path'], ())
7fc6a3 294
CM 295     def test_call_with_vh_root4(self):
def68d 296         environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar/baz')
7fc6a3 297         baz = DummyContext(None, 'baz')
CM 298         bar = DummyContext(baz, 'bar')
299         foo = DummyContext(bar, 'foo')
300         root = DummyContext(foo, 'root')
301         policy = self._makeOne(root)
ebcdc7 302         request = DummyRequest(environ, path_info=text_('/'))
f426e5 303         result = policy(request)
7fc6a3 304         self.assertEqual(result['context'], baz)
CM 305         self.assertEqual(result['view_name'], '')
306         self.assertEqual(result['subpath'], ())
e6c2d2 307         self.assertEqual(result['traversed'],
CM 308                          (text_('foo'), text_('bar'), text_('baz')))
7fc6a3 309         self.assertEqual(result['root'], root)
CM 310         self.assertEqual(result['virtual_root'], baz)
e6c2d2 311         self.assertEqual(result['virtual_root_path'],
CM 312                          (text_('foo'), text_('bar'), text_('baz')))
1cd598 313
CM 314     def test_call_with_vh_root_path_root(self):
315         policy = self._makeOne(None)
def68d 316         environ = self._getEnviron(HTTP_X_VHM_ROOT='/')
ebcdc7 317         request = DummyRequest(environ, path_info=text_('/'))
f426e5 318         result = policy(request)
1cd598 319         self.assertEqual(result['context'], None)
CM 320         self.assertEqual(result['view_name'], '')
321         self.assertEqual(result['subpath'], ())
322         self.assertEqual(result['traversed'], ())
7fc6a3 323         self.assertEqual(result['root'], policy.root)
1cd598 324         self.assertEqual(result['virtual_root'], policy.root)
CM 325         self.assertEqual(result['virtual_root_path'], ())
65f3f8 326
92dcb5 327     def test_call_with_vh_root_highorder(self):
def68d 328         path = text_(b'Qu\xc3\xa9bec', 'utf-8')
92dcb5 329         bar = DummyContext(None, 'bar')
def68d 330         foo = DummyContext(bar, path)
92dcb5 331         root = DummyContext(foo, 'root')
CM 332         policy = self._makeOne(root)
bc37a5 333         if PY2:
92dcb5 334             vhm_root = b'/Qu\xc3\xa9bec'
bc37a5 335         else:
MM 336             vhm_root = b'/Qu\xc3\xa9bec'.decode('latin-1')
def68d 337         environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root)
ebcdc7 338         request = DummyRequest(environ, path_info=text_('/bar'))
92dcb5 339         result = policy(request)
CM 340         self.assertEqual(result['context'], bar)
341         self.assertEqual(result['view_name'], '')
342         self.assertEqual(result['subpath'], ())
343         self.assertEqual(
344             result['traversed'],
def68d 345             (path, text_('bar'))
92dcb5 346             )
CM 347         self.assertEqual(result['root'], policy.root)
348         self.assertEqual(result['virtual_root'], foo)
349         self.assertEqual(
350             result['virtual_root_path'],
def68d 351             (path,)
92dcb5 352             )
CM 353
def68d 354     def test_path_info_raises_unicodedecodeerror(self):
f84147 355         from pyramid.exceptions import URLDecodeError
217070 356         foo = DummyContext()
TS 357         root = DummyContext(foo)
358         policy = self._makeOne(root)
def68d 359         environ = self._getEnviron()
ebcdc7 360         toraise = UnicodeDecodeError('ascii', b'a', 2, 3, '5')
def68d 361         request = DummyRequest(environ, toraise=toraise)
CM 362         request.matchdict = None
f84147 363         self.assertRaises(URLDecodeError, policy, request)
217070 364
dfc2b6 365     def test_withroute_nothingfancy(self):
92c3e5 366         resource = DummyContext()
CM 367         traverser = self._makeOne(resource)
def68d 368         request = DummyRequest({})
CM 369         request.matchdict = {}
f426e5 370         result = traverser(request)
92c3e5 371         self.assertEqual(result['context'], resource)
dfc2b6 372         self.assertEqual(result['view_name'], '')
6ecdbc 373         self.assertEqual(result['subpath'], ())
1cd598 374         self.assertEqual(result['traversed'], ())
92c3e5 375         self.assertEqual(result['root'], resource)
CM 376         self.assertEqual(result['virtual_root'], resource)
1cd598 377         self.assertEqual(result['virtual_root_path'], ())
dfc2b6 378
25cbe1 379     def test_withroute_with_subpath_string(self):
92c3e5 380         resource = DummyContext()
CM 381         traverser = self._makeOne(resource)
def68d 382         matchdict = {'subpath':'/a/b/c'}
CM 383         request = DummyRequest({})
384         request.matchdict = matchdict
f426e5 385         result = traverser(request)
92c3e5 386         self.assertEqual(result['context'], resource)
dfc2b6 387         self.assertEqual(result['view_name'], '')
6ecdbc 388         self.assertEqual(result['subpath'], ('a', 'b','c'))
1cd598 389         self.assertEqual(result['traversed'], ())
92c3e5 390         self.assertEqual(result['root'], resource)
CM 391         self.assertEqual(result['virtual_root'], resource)
1cd598 392         self.assertEqual(result['virtual_root_path'], ())
dfc2b6 393
25cbe1 394     def test_withroute_with_subpath_tuple(self):
92c3e5 395         resource = DummyContext()
CM 396         traverser = self._makeOne(resource)
def68d 397         matchdict = {'subpath':('a', 'b', 'c')}
CM 398         request = DummyRequest({})
399         request.matchdict = matchdict
f426e5 400         result = traverser(request)
92c3e5 401         self.assertEqual(result['context'], resource)
25cbe1 402         self.assertEqual(result['view_name'], '')
CM 403         self.assertEqual(result['subpath'], ('a', 'b','c'))
404         self.assertEqual(result['traversed'], ())
92c3e5 405         self.assertEqual(result['root'], resource)
CM 406         self.assertEqual(result['virtual_root'], resource)
25cbe1 407         self.assertEqual(result['virtual_root_path'], ())
CM 408
409     def test_withroute_and_traverse_string(self):
92c3e5 410         resource = DummyContext()
CM 411         traverser = self._makeOne(resource)
ebcdc7 412         matchdict =  {'traverse':text_('foo/bar')}
def68d 413         request = DummyRequest({})
CM 414         request.matchdict = matchdict
f426e5 415         result = traverser(request)
92c3e5 416         self.assertEqual(result['context'], resource)
dfc2b6 417         self.assertEqual(result['view_name'], 'foo')
6ecdbc 418         self.assertEqual(result['subpath'], ('bar',))
1cd598 419         self.assertEqual(result['traversed'], ())
92c3e5 420         self.assertEqual(result['root'], resource)
CM 421         self.assertEqual(result['virtual_root'], resource)
1cd598 422         self.assertEqual(result['virtual_root_path'], ())
dfc2b6 423
25cbe1 424     def test_withroute_and_traverse_tuple(self):
92c3e5 425         resource = DummyContext()
CM 426         traverser = self._makeOne(resource)
def68d 427         matchdict = {'traverse':('foo', 'bar')}
CM 428         request = DummyRequest({})
429         request.matchdict = matchdict
f426e5 430         result = traverser(request)
92c3e5 431         self.assertEqual(result['context'], resource)
25cbe1 432         self.assertEqual(result['view_name'], 'foo')
CM 433         self.assertEqual(result['subpath'], ('bar',))
434         self.assertEqual(result['traversed'], ())
92c3e5 435         self.assertEqual(result['root'], resource)
CM 436         self.assertEqual(result['virtual_root'], resource)
25cbe1 437         self.assertEqual(result['virtual_root_path'], ())
CM 438
1db5c4 439     def test_withroute_and_traverse_empty(self):
CM 440         resource = DummyContext()
441         traverser = self._makeOne(resource)
def68d 442         matchdict = {'traverse':''}
CM 443         request = DummyRequest({})
444         request.matchdict = matchdict
f426e5 445         result = traverser(request)
1db5c4 446         self.assertEqual(result['context'], resource)
CM 447         self.assertEqual(result['view_name'], '')
448         self.assertEqual(result['subpath'], ())
449         self.assertEqual(result['traversed'], ())
450         self.assertEqual(result['root'], resource)
451         self.assertEqual(result['virtual_root'], resource)
452         self.assertEqual(result['virtual_root_path'], ())
f426e5 453
ece96f 454     def test_withroute_and_traverse_and_vroot(self):
CM 455         abc = DummyContext()
456         resource = DummyContext(next=abc)
457         environ = self._getEnviron(HTTP_X_VHM_ROOT='/abc')
458         request = DummyRequest(environ)
459         traverser = self._makeOne(resource)
460         matchdict =  {'traverse':text_('/foo/bar')}
461         request.matchdict = matchdict
462         result = traverser(request)
463         self.assertEqual(result['context'], abc)
464         self.assertEqual(result['view_name'], 'foo')
465         self.assertEqual(result['subpath'], ('bar',))
466         self.assertEqual(result['traversed'], ('abc', 'foo'))
467         self.assertEqual(result['root'], resource)
468         self.assertEqual(result['virtual_root'], abc)
469         self.assertEqual(result['virtual_root_path'], ('abc',))
470         
bb5d64 471 class FindInterfaceTests(unittest.TestCase):
eb6afe 472     def _callFUT(self, context, iface):
b60bdb 473         from pyramid.traversal import find_interface
eb6afe 474         return find_interface(context, iface)
bb5d64 475
0f5d8b 476     def test_it_interface(self):
bb5d64 477         baz = DummyContext()
CM 478         bar = DummyContext(baz)
479         foo = DummyContext(bar)
480         root = DummyContext(foo)
481         root.__parent__ = None
482         root.__name__ = 'root'
483         foo.__parent__ = root
484         foo.__name__ = 'foo'
485         bar.__parent__ = foo
486         bar.__name__ = 'bar'
487         baz.__parent__ = bar
488         baz.__name__ = 'baz'
489         from zope.interface import directlyProvides
490         from zope.interface import Interface
491         class IFoo(Interface):
492             pass
493         directlyProvides(root, IFoo)
eb6afe 494         result = self._callFUT(baz, IFoo)
bb5d64 495         self.assertEqual(result.__name__, 'root')
CM 496
0f5d8b 497     def test_it_class(self):
CM 498         class DummyRoot(object):
499             def __init__(self, child):
500                 self.child = child
501         baz = DummyContext()
502         bar = DummyContext(baz)
503         foo = DummyContext(bar)
504         root = DummyRoot(foo)
505         root.__parent__ = None
506         root.__name__ = 'root'
507         foo.__parent__ = root
508         foo.__name__ = 'foo'
509         bar.__parent__ = foo
510         bar.__name__ = 'bar'
511         baz.__parent__ = bar
512         baz.__name__ = 'baz'
513         result = self._callFUT(baz, DummyRoot)
514         self.assertEqual(result.__name__, 'root')
515
cc5e49 516 class FindRootTests(unittest.TestCase):
eb6afe 517     def _callFUT(self, context):
b60bdb 518         from pyramid.traversal import find_root
eb6afe 519         return find_root(context)
cc5e49 520
CM 521     def test_it(self):
522         dummy = DummyContext()
523         baz = DummyContext()
524         baz.__parent__ = dummy
525         baz.__name__ = 'baz'
526         dummy.__parent__ = None
527         dummy.__name__ = None
eb6afe 528         result = self._callFUT(baz)
cc5e49 529         self.assertEqual(result, dummy)
CM 530
92c3e5 531 class FindResourceTests(unittest.TestCase):
eb6afe 532     def _callFUT(self, context, name):
92c3e5 533         from pyramid.traversal import find_resource
CM 534         return find_resource(context, name)
cc5e49 535
077c3c 536     def _registerTraverser(self, traverser):
b60bdb 537         from pyramid.threadlocal import get_current_registry
6fec21 538         reg = get_current_registry()
b60bdb 539         from pyramid.interfaces import ITraverser
cc5e49 540         from zope.interface import Interface
6fec21 541         reg.registerAdapter(traverser, (Interface,), ITraverser)
cc5e49 542
dbab77 543     def test_list(self):
92c3e5 544         resource = DummyContext()
CM 545         traverser = make_traverser({'context':resource, 'view_name':''})
077c3c 546         self._registerTraverser(traverser)
92c3e5 547         result = self._callFUT(resource, [''])
CM 548         self.assertEqual(result, resource)
549         self.assertEqual(resource.request.environ['PATH_INFO'], '/')
dbab77 550
CM 551     def test_generator(self):
92c3e5 552         resource = DummyContext()
CM 553         traverser = make_traverser({'context':resource, 'view_name':''})
077c3c 554         self._registerTraverser(traverser)
dbab77 555         def foo():
CM 556             yield ''
92c3e5 557         result = self._callFUT(resource, foo())
CM 558         self.assertEqual(result, resource)
559         self.assertEqual(resource.request.environ['PATH_INFO'], '/')
dbab77 560
CM 561     def test_self_string_found(self):
92c3e5 562         resource = DummyContext()
CM 563         traverser = make_traverser({'context':resource, 'view_name':''})
077c3c 564         self._registerTraverser(traverser)
92c3e5 565         result = self._callFUT(resource, '')
CM 566         self.assertEqual(result, resource)
567         self.assertEqual(resource.request.environ['PATH_INFO'], '')
dbab77 568
CM 569     def test_self_tuple_found(self):
92c3e5 570         resource = DummyContext()
CM 571         traverser = make_traverser({'context':resource, 'view_name':''})
077c3c 572         self._registerTraverser(traverser)
92c3e5 573         result = self._callFUT(resource, ())
CM 574         self.assertEqual(result, resource)
575         self.assertEqual(resource.request.environ['PATH_INFO'], '')
dbab77 576
CM 577     def test_relative_string_found(self):
92c3e5 578         resource = DummyContext()
cc5e49 579         baz = DummyContext()
916f88 580         traverser = make_traverser({'context':baz, 'view_name':''})
077c3c 581         self._registerTraverser(traverser)
92c3e5 582         result = self._callFUT(resource, 'baz')
cc5e49 583         self.assertEqual(result, baz)
92c3e5 584         self.assertEqual(resource.request.environ['PATH_INFO'], 'baz')
cc5e49 585
dbab77 586     def test_relative_tuple_found(self):
92c3e5 587         resource = DummyContext()
dbab77 588         baz = DummyContext()
916f88 589         traverser = make_traverser({'context':baz, 'view_name':''})
077c3c 590         self._registerTraverser(traverser)
92c3e5 591         result = self._callFUT(resource, ('baz',))
dbab77 592         self.assertEqual(result, baz)
92c3e5 593         self.assertEqual(resource.request.environ['PATH_INFO'], 'baz')
dbab77 594
CM 595     def test_relative_string_notfound(self):
92c3e5 596         resource = DummyContext()
cc5e49 597         baz = DummyContext()
916f88 598         traverser = make_traverser({'context':baz, 'view_name':'bar'})
077c3c 599         self._registerTraverser(traverser)
92c3e5 600         self.assertRaises(KeyError, self._callFUT, resource, 'baz')
CM 601         self.assertEqual(resource.request.environ['PATH_INFO'], 'baz')
cc5e49 602
dbab77 603     def test_relative_tuple_notfound(self):
92c3e5 604         resource = DummyContext()
cc5e49 605         baz = DummyContext()
916f88 606         traverser = make_traverser({'context':baz, 'view_name':'bar'})
077c3c 607         self._registerTraverser(traverser)
92c3e5 608         self.assertRaises(KeyError, self._callFUT, resource, ('baz',))
CM 609         self.assertEqual(resource.request.environ['PATH_INFO'], 'baz')
cc5e49 610
dbab77 611     def test_absolute_string_found(self):
CM 612         root = DummyContext()
92c3e5 613         resource = DummyContext()
CM 614         resource.__parent__ = root
615         resource.__name__ = 'baz'
916f88 616         traverser = make_traverser({'context':root, 'view_name':''})
077c3c 617         self._registerTraverser(traverser)
92c3e5 618         result = self._callFUT(resource, '/')
dbab77 619         self.assertEqual(result, root)
CM 620         self.assertEqual(root.wascontext, True)
6fec21 621         self.assertEqual(root.request.environ['PATH_INFO'], '/')
cc5e49 622
dbab77 623     def test_absolute_tuple_found(self):
CM 624         root = DummyContext()
92c3e5 625         resource = DummyContext()
CM 626         resource.__parent__ = root
627         resource.__name__ = 'baz'
916f88 628         traverser = make_traverser({'context':root, 'view_name':''})
077c3c 629         self._registerTraverser(traverser)
92c3e5 630         result = self._callFUT(resource, ('',))
dbab77 631         self.assertEqual(result, root)
CM 632         self.assertEqual(root.wascontext, True)
6fec21 633         self.assertEqual(root.request.environ['PATH_INFO'], '/')
dbab77 634
CM 635     def test_absolute_string_notfound(self):
636         root = DummyContext()
92c3e5 637         resource = DummyContext()
CM 638         resource.__parent__ = root
639         resource.__name__ = 'baz'
916f88 640         traverser = make_traverser({'context':root, 'view_name':'fuz'})
077c3c 641         self._registerTraverser(traverser)
92c3e5 642         self.assertRaises(KeyError, self._callFUT, resource, '/')
dbab77 643         self.assertEqual(root.wascontext, True)
6fec21 644         self.assertEqual(root.request.environ['PATH_INFO'], '/')
dbab77 645
CM 646     def test_absolute_tuple_notfound(self):
647         root = DummyContext()
92c3e5 648         resource = DummyContext()
CM 649         resource.__parent__ = root
650         resource.__name__ = 'baz'
916f88 651         traverser = make_traverser({'context':root, 'view_name':'fuz'})
077c3c 652         self._registerTraverser(traverser)
92c3e5 653         self.assertRaises(KeyError, self._callFUT, resource, ('',))
dbab77 654         self.assertEqual(root.wascontext, True)
6fec21 655         self.assertEqual(root.request.environ['PATH_INFO'], '/')
916f88 656
a66593 657     def test_absolute_unicode_found(self):
CM 658         # test for bug wiggy found in wild, traceback stack:
659         # root = u'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF'
92c3e5 660         # wiggy's code: section=find_resource(page, root)
CM 661         # find_resource L76: D = traverse(resource, path)
a66593 662         # traverse L291: return traverser(request)
CM 663         # __call__ line 568: vpath_tuple = traversal_path(vpath)
664         # lru_cached line 91: f(*arg)
665         # traversal_path line 443: path.encode('ascii')
666         # UnicodeEncodeError: 'ascii' codec can't encode characters in
667         #     position 1-12: ordinal not in range(128)
668         #
669         # solution: encode string to ascii in pyramid.traversal.traverse
670         # before passing it along to webob as path_info
92c3e5 671         from pyramid.traversal import ResourceTreeTraverser
a66593 672         unprintable = DummyContext()
CM 673         root = DummyContext(unprintable)
674         unprintable.__parent__ = root
e6c2d2 675         unprintable.__name__ = text_(
a84e17 676             b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', 'utf-8')
a66593 677         root.__parent__ = None
CM 678         root.__name__ = None
92c3e5 679         traverser = ResourceTreeTraverser
a66593 680         self._registerTraverser(traverser)
e6c2d2 681         result = self._callFUT(
CM 682             root,
5942ec 683             text_(b'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF')
CM 684             )
a66593 685         self.assertEqual(result, unprintable)
358dc2 686
92c3e5 687 class ResourcePathTests(unittest.TestCase):
CM 688     def _callFUT(self, resource, *elements):
689         from pyramid.traversal import resource_path
690         return resource_path(resource, *elements)
c750ba 691
CM 692     def test_it(self):
693         baz = DummyContext()
694         bar = DummyContext(baz)
695         foo = DummyContext(bar)
696         root = DummyContext(foo)
697         root.__parent__ = None
698         root.__name__ = None
699         foo.__parent__ = root
700         foo.__name__ = 'foo '
701         bar.__parent__ = foo
702         bar.__name__ = 'bar'
703         baz.__parent__ = bar
704         baz.__name__ = 'baz'
eb6afe 705         result = self._callFUT(baz, 'this/theotherthing', 'that')
a97a70 706         self.assertEqual(result, '/foo%20/bar/baz/this%2Ftheotherthing/that')
CM 707
708     def test_root_default(self):
709         root = DummyContext()
710         root.__parent__ = None
711         root.__name__ = None
712         result = self._callFUT(root)
713         self.assertEqual(result, '/')
8e037f 714
CM 715     def test_root_default_emptystring(self):
716         root = DummyContext()
717         root.__parent__ = None
718         root.__name__ = ''
719         result = self._callFUT(root)
720         self.assertEqual(result, '/')
721
722     def test_root_object_nonnull_name_direct(self):
723         root = DummyContext()
724         root.__parent__ = None
725         root.__name__ = 'flubadub'
726         result = self._callFUT(root)
727         self.assertEqual(result, 'flubadub') # insane case
728
729     def test_root_object_nonnull_name_indirect(self):
730         root = DummyContext()
731         root.__parent__ = None
732         root.__name__ = 'flubadub'
733         other = DummyContext()
734         other.__parent__ = root
735         other.__name__ = 'barker'
736         result = self._callFUT(other)
737         self.assertEqual(result, 'flubadub/barker') # insane case
738
a97a70 739     def test_nonroot_default(self):
CM 740         root = DummyContext()
741         root.__parent__ = None
742         root.__name__ = None
743         other = DummyContext()
744         other.__parent__ = root
745         other.__name__ = 'other'
746         result = self._callFUT(other)
747         self.assertEqual(result, '/other')
b1de62 748
CM 749     def test_path_with_None_itermediate_names(self):
750         root = DummyContext()
751         root.__parent__ = None
752         root.__name__ = None
753         other = DummyContext()
754         other.__parent__ = root
755         other.__name__ = None
756         other2 = DummyContext()
757         other2.__parent__ = other
758         other2.__name__ = 'other2'
759         result = self._callFUT(other2)
760         self.assertEqual(result, '//other2')
a97a70 761
92c3e5 762 class ResourcePathTupleTests(unittest.TestCase):
CM 763     def _callFUT(self, resource, *elements):
764         from pyramid.traversal import resource_path_tuple
765         return resource_path_tuple(resource, *elements)
a97a70 766
CM 767     def test_it(self):
768         baz = DummyContext()
769         bar = DummyContext(baz)
770         foo = DummyContext(bar)
771         root = DummyContext(foo)
772         root.__parent__ = None
773         root.__name__ = None
774         foo.__parent__ = root
775         foo.__name__ = 'foo '
776         bar.__parent__ = foo
777         bar.__name__ = 'bar'
778         baz.__parent__ = bar
779         baz.__name__ = 'baz'
780         result = self._callFUT(baz, 'this/theotherthing', 'that')
dbab77 781         self.assertEqual(result, ('','foo ', 'bar', 'baz', 'this/theotherthing',
CM 782                                   'that'))
c750ba 783
eb6afe 784     def test_root_default(self):
6d4015 785         root = DummyContext()
CM 786         root.__parent__ = None
787         root.__name__ = None
eb6afe 788         result = self._callFUT(root)
dbab77 789         self.assertEqual(result, ('',))
51c305 790
1db5c4 791     def test_root_default_emptystring_name(self):
CM 792         root = DummyContext()
793         root.__parent__ = None
794         root.__name__ = ''
795         other = DummyContext()
796         other.__parent__ = root
797         other.__name__ = 'other'
798         result = self._callFUT(other)
799         self.assertEqual(result, ('', 'other',))
800
eb6afe 801     def test_nonroot_default(self):
CM 802         root = DummyContext()
803         root.__parent__ = None
804         root.__name__ = None
805         other = DummyContext()
806         other.__parent__ = root
807         other.__name__ = 'other'
808         result = self._callFUT(other)
dbab77 809         self.assertEqual(result, ('', 'other'))
c750ba 810
b1de62 811     def test_path_with_None_itermediate_names(self):
CM 812         root = DummyContext()
813         root.__parent__ = None
814         root.__name__ = None
815         other = DummyContext()
816         other.__parent__ = root
817         other.__name__ = None
818         other2 = DummyContext()
819         other2.__parent__ = other
820         other2.__name__ = 'other2'
821         result = self._callFUT(other2)
822         self.assertEqual(result, ('', '', 'other2'))
823
a97a70 824 class QuotePathSegmentTests(unittest.TestCase):
CM 825     def _callFUT(self, s):
b60bdb 826         from pyramid.traversal import quote_path_segment
a97a70 827         return quote_path_segment(s)
CM 828
829     def test_unicode(self):
a84e17 830         la = text_(b'/La Pe\xc3\xb1a', 'utf-8')
a97a70 831         result = self._callFUT(la)
CM 832         self.assertEqual(result, '%2FLa%20Pe%C3%B1a')
833
834     def test_string(self):
835         s = '/ hello!'
836         result = self._callFUT(s)
f52759 837         self.assertEqual(result, '%2F%20hello!')
a97a70 838
fcbd7b 839     def test_int(self):
CM 840         s = 12345
841         result = self._callFUT(s)
842         self.assertEqual(result, '12345')
843         
844     def test_long(self):
475532 845         from pyramid.compat import long
fcbd7b 846         import sys
a84e17 847         s = long(sys.maxsize + 1)
fcbd7b 848         result = self._callFUT(s)
CM 849         expected = str(s)
850         self.assertEqual(result, expected)
851
852     def test_other(self):
853         class Foo(object):
854             def __str__(self):
855                 return 'abc'
856         s = Foo()
857         result = self._callFUT(s)
858         self.assertEqual(result, 'abc')
859
118ea0 860 class ResourceURLTests(unittest.TestCase):
e62e47 861     def _makeOne(self, context, url):
CM 862         return self._getTargetClass()(context, url)
863
864     def _getTargetClass(self):
118ea0 865         from pyramid.traversal import ResourceURL
CM 866         return ResourceURL
e62e47 867
118ea0 868     def test_instance_conforms_to_IResourceURL(self):
CM 869         from pyramid.interfaces import IResourceURL
870         from zope.interface.verify import verifyObject
871         context = DummyContext()
872         request = DummyRequest()
873         verifyObject(IResourceURL, self._makeOne(context, request))
bac5b3 874
118ea0 875     def test_IResourceURL_attributes_with_vroot(self):
CM 876         from pyramid.interfaces import VH_ROOT_KEY
877         root = DummyContext()
878         root.__parent__ = None
879         root.__name__ = None
880         one = DummyContext()
881         one.__parent__ = root
882         one.__name__ = 'one'
883         two = DummyContext()
884         two.__parent__ = one
885         two.__name__ = 'two'
886         environ = {VH_ROOT_KEY:'/one'}
887         request = DummyRequest(environ)
888         context_url = self._makeOne(two, request)
889         self.assertEqual(context_url.physical_path, '/one/two/')
890         self.assertEqual(context_url.virtual_path, '/two/')
db0185 891         self.assertEqual(context_url.physical_path_tuple, ('', 'one', 'two',''))
CM 892         self.assertEqual(context_url.virtual_path_tuple, ('', 'two', ''))
893         
894     def test_IResourceURL_attributes_vroot_ends_with_slash(self):
895         from pyramid.interfaces import VH_ROOT_KEY
896         root = DummyContext()
897         root.__parent__ = None
898         root.__name__ = None
899         one = DummyContext()
900         one.__parent__ = root
901         one.__name__ = 'one'
902         two = DummyContext()
903         two.__parent__ = one
904         two.__name__ = 'two'
905         environ = {VH_ROOT_KEY:'/one/'}
906         request = DummyRequest(environ)
907         context_url = self._makeOne(two, request)
908         self.assertEqual(context_url.physical_path, '/one/two/')
909         self.assertEqual(context_url.virtual_path, '/two/')
910         self.assertEqual(context_url.physical_path_tuple, ('', 'one', 'two',''))
911         self.assertEqual(context_url.virtual_path_tuple, ('', 'two', ''))
912         
118ea0 913     def test_IResourceURL_attributes_no_vroot(self):
CM 914         root = DummyContext()
915         root.__parent__ = None
916         root.__name__ = None
917         one = DummyContext()
918         one.__parent__ = root
919         one.__name__ = 'one'
920         two = DummyContext()
921         two.__parent__ = one
922         two.__name__ = 'two'
923         environ = {}
924         request = DummyRequest(environ)
925         context_url = self._makeOne(two, request)
926         self.assertEqual(context_url.physical_path, '/one/two/')
927         self.assertEqual(context_url.virtual_path, '/one/two/')
db0185 928         self.assertEqual(context_url.physical_path_tuple, ('', 'one', 'two',''))
CM 929         self.assertEqual(context_url.virtual_path_tuple, ('', 'one', 'two', ''))
930
e62e47 931 class TestVirtualRoot(unittest.TestCase):
CM 932     def setUp(self):
933         cleanUp()
934
935     def tearDown(self):
936         cleanUp()
937
92c3e5 938     def _callFUT(self, resource, request):
b60bdb 939         from pyramid.traversal import virtual_root
92c3e5 940         return virtual_root(resource, request)
e62e47 941
7ba907 942     def _registerTraverser(self, traverser):
MM 943         from pyramid.threadlocal import get_current_registry
944         reg = get_current_registry()
945         from pyramid.interfaces import ITraverser
e62e47 946         from zope.interface import Interface
7ba907 947         reg.registerAdapter(traverser, (Interface,), ITraverser)
MM 948
949     def test_virtual_root_no_virtual_root_path(self):
950         root = DummyContext()
951         root.__name__ = None
952         root.__parent__ = None
953         one = DummyContext()
954         one.__name__ = 'one'
955         one.__parent__ = root
956         request = DummyRequest()
957         result = self._callFUT(one, request)
958         self.assertEqual(result, root)
959
960     def test_virtual_root_no_virtual_root_path_with_root_on_request(self):
e62e47 961         context = DummyContext()
7ba907 962         context.__parent__ = None
MM 963         request = DummyRequest()
964         request.root = DummyContext()
e62e47 965         result = self._callFUT(context, request)
7ba907 966         self.assertEqual(result, request.root)
MM 967
968     def test_virtual_root_with_virtual_root_path(self):
969         from pyramid.interfaces import VH_ROOT_KEY
970         root = DummyContext()
971         root.__parent__ = None
972         context = DummyContext()
973         context.__name__ = 'one'
974         context.__parent__ = root
975         traversed_to = DummyContext()
976         environ = {VH_ROOT_KEY:'/one'}
977         request = DummyRequest(environ)
978         traverser = make_traverser({'context':traversed_to, 'view_name':''})
979         self._registerTraverser(traverser)
980         result = self._callFUT(context, request)
981         self.assertEqual(result, traversed_to)
982         self.assertEqual(root.request.environ['PATH_INFO'], '/one')
e62e47 983
160f01 984     def test_default(self):
CM 985         context = DummyContext()
6fec21 986         request = _makeRequest()
160f01 987         request.environ['PATH_INFO'] = '/'
CM 988         result = self._callFUT(context, request)
989         self.assertEqual(result, context)
990
45d08c 991     def test_default_no_registry_on_request(self):
CM 992         context = DummyContext()
993         request = _makeRequest()
994         del request.registry
995         request.environ['PATH_INFO'] = '/'
996         result = self._callFUT(context, request)
997         self.assertEqual(result, context)
998
916f88 999 class TraverseTests(unittest.TestCase):
CM 1000     def setUp(self):
1001         cleanUp()
1002
1003     def tearDown(self):
1004         cleanUp()
1005
1006     def _callFUT(self, context, name):
b60bdb 1007         from pyramid.traversal import traverse
916f88 1008         return traverse(context, name)
CM 1009
077c3c 1010     def _registerTraverser(self, traverser):
b60bdb 1011         from pyramid.threadlocal import get_current_registry
6fec21 1012         reg = get_current_registry()
b60bdb 1013         from pyramid.interfaces import ITraverser
916f88 1014         from zope.interface import Interface
6fec21 1015         reg.registerAdapter(traverser, (Interface,), ITraverser)
CM 1016
1017     def test_request_has_registry(self):
b60bdb 1018         from pyramid.threadlocal import get_current_registry
92c3e5 1019         resource = DummyContext()
CM 1020         traverser = make_traverser({'context':resource, 'view_name':''})
6fec21 1021         self._registerTraverser(traverser)
92c3e5 1022         self._callFUT(resource, [''])
CM 1023         self.assertEqual(resource.request.registry, get_current_registry())
916f88 1024
CM 1025     def test_list(self):
92c3e5 1026         resource = DummyContext()
CM 1027         traverser = make_traverser({'context':resource, 'view_name':''})
077c3c 1028         self._registerTraverser(traverser)
92c3e5 1029         self._callFUT(resource, [''])
CM 1030         self.assertEqual(resource.request.environ['PATH_INFO'], '/')
916f88 1031
CM 1032     def test_generator(self):
92c3e5 1033         resource = DummyContext()
CM 1034         traverser = make_traverser({'context':resource, 'view_name':''})
077c3c 1035         self._registerTraverser(traverser)
916f88 1036         def foo():
CM 1037             yield ''
92c3e5 1038         self._callFUT(resource, foo())
CM 1039         self.assertEqual(resource.request.environ['PATH_INFO'], '/')
916f88 1040
CM 1041     def test_self_string_found(self):
92c3e5 1042         resource = DummyContext()
CM 1043         traverser = make_traverser({'context':resource, 'view_name':''})
077c3c 1044         self._registerTraverser(traverser)
92c3e5 1045         self._callFUT(resource, '')
CM 1046         self.assertEqual(resource.request.environ['PATH_INFO'], '')
916f88 1047
f84147 1048     def test_self_unicode_found(self):
CM 1049         resource = DummyContext()
1050         traverser = make_traverser({'context':resource, 'view_name':''})
1051         self._registerTraverser(traverser)
1052         self._callFUT(resource, text_(''))
1053         self.assertEqual(resource.request.environ['PATH_INFO'], '')
1054
916f88 1055     def test_self_tuple_found(self):
92c3e5 1056         resource = DummyContext()
CM 1057         traverser = make_traverser({'context':resource, 'view_name':''})
077c3c 1058         self._registerTraverser(traverser)
92c3e5 1059         self._callFUT(resource, ())
CM 1060         self.assertEqual(resource.request.environ['PATH_INFO'], '')
916f88 1061
CM 1062     def test_relative_string_found(self):
92c3e5 1063         resource = DummyContext()
916f88 1064         baz = DummyContext()
CM 1065         traverser = make_traverser({'context':baz, 'view_name':''})
077c3c 1066         self._registerTraverser(traverser)
92c3e5 1067         self._callFUT(resource, 'baz')
CM 1068         self.assertEqual(resource.request.environ['PATH_INFO'], 'baz')
916f88 1069
CM 1070     def test_relative_tuple_found(self):
92c3e5 1071         resource = DummyContext()
916f88 1072         baz = DummyContext()
CM 1073         traverser = make_traverser({'context':baz, 'view_name':''})
077c3c 1074         self._registerTraverser(traverser)
92c3e5 1075         self._callFUT(resource, ('baz',))
CM 1076         self.assertEqual(resource.request.environ['PATH_INFO'], 'baz')
916f88 1077
CM 1078     def test_absolute_string_found(self):
1079         root = DummyContext()
92c3e5 1080         resource = DummyContext()
CM 1081         resource.__parent__ = root
1082         resource.__name__ = 'baz'
916f88 1083         traverser = make_traverser({'context':root, 'view_name':''})
077c3c 1084         self._registerTraverser(traverser)
92c3e5 1085         self._callFUT(resource, '/')
916f88 1086         self.assertEqual(root.wascontext, True)
6fec21 1087         self.assertEqual(root.request.environ['PATH_INFO'], '/')
916f88 1088
CM 1089     def test_absolute_tuple_found(self):
1090         root = DummyContext()
92c3e5 1091         resource = DummyContext()
CM 1092         resource.__parent__ = root
1093         resource.__name__ = 'baz'
916f88 1094         traverser = make_traverser({'context':root, 'view_name':''})
077c3c 1095         self._registerTraverser(traverser)
92c3e5 1096         self._callFUT(resource, ('',))
916f88 1097         self.assertEqual(root.wascontext, True)
6fec21 1098         self.assertEqual(root.request.environ['PATH_INFO'], '/')
916f88 1099
391afe 1100     def test_empty_sequence(self):
CM 1101         root = DummyContext()
92c3e5 1102         resource = DummyContext()
CM 1103         resource.__parent__ = root
1104         resource.__name__ = 'baz'
391afe 1105         traverser = make_traverser({'context':root, 'view_name':''})
077c3c 1106         self._registerTraverser(traverser)
92c3e5 1107         self._callFUT(resource, [])
CM 1108         self.assertEqual(resource.wascontext, True)
1109         self.assertEqual(resource.request.environ['PATH_INFO'], '')
391afe 1110
164677 1111     def test_default_traverser(self):
92c3e5 1112         resource = DummyContext()
CM 1113         result = self._callFUT(resource, '')
e46105 1114         self.assertEqual(result['view_name'], '')
92c3e5 1115         self.assertEqual(result['context'], resource)
c32af0 1116
81a833 1117     def test_requestfactory_overridden(self):
b60bdb 1118         from pyramid.interfaces import IRequestFactory
CM 1119         from pyramid.request import Request
1120         from pyramid.threadlocal import get_current_registry
81a833 1121         reg = get_current_registry()
CM 1122         class MyRequest(Request):
1123             pass
1124         reg.registerUtility(MyRequest, IRequestFactory)
92c3e5 1125         resource = DummyContext()
CM 1126         traverser = make_traverser({'context':resource, 'view_name':''})
81a833 1127         self._registerTraverser(traverser)
92c3e5 1128         self._callFUT(resource, [''])
CM 1129         self.assertEqual(resource.request.__class__, MyRequest)
81a833 1130
eac7c4 1131 class TestDefaultRootFactory(unittest.TestCase):
CM 1132     def _getTargetClass(self):
b60bdb 1133         from pyramid.traversal import DefaultRootFactory
eac7c4 1134         return DefaultRootFactory
CM 1135
1136     def _makeOne(self, environ):
1137         return self._getTargetClass()(environ)
1138
95e971 1139     def test_it(self):
CM 1140         class DummyRequest(object):
1141             pass
51c305 1142         root = self._makeOne(DummyRequest())
eac7c4 1143         self.assertEqual(root.__parent__, None)
CM 1144         self.assertEqual(root.__name__, None)
1145
1db5c4 1146 class Test__join_path_tuple(unittest.TestCase):
CM 1147     def _callFUT(self, tup):
1148         from pyramid.traversal import _join_path_tuple
1149         return _join_path_tuple(tup)
1150
1151     def test_empty_tuple(self):
1152         # tests "or '/'" case
1153         result = self._callFUT(())
1154         self.assertEqual(result, '/')
1155
1156     def test_nonempty_tuple(self):
1157         result = self._callFUT(('x',))
1158         self.assertEqual(result, 'x')
eac7c4 1159
f52759 1160     def test_segments_with_unsafes(self):
MK 1161         safe_segments = tuple(u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~!$&'()*+,;=:@")
1162         result = self._callFUT(safe_segments)
1163         self.assertEqual(result, u'/'.join(safe_segments))
1164         unsafe_segments = tuple(chr(i) for i in range(0x20, 0x80) if not chr(i) in safe_segments) + (u'あ',)
1165         result = self._callFUT(unsafe_segments)
1166         self.assertEqual(result, u'/'.join(''.join('%%%02X' % (ord(c) if isinstance(c, str) else c) for c in unsafe_segment.encode('utf-8')) for unsafe_segment in unsafe_segments))
1167
1168
916f88 1169 def make_traverser(result):
cc5e49 1170     class DummyTraverser(object):
CM 1171         def __init__(self, context):
358dc2 1172             self.context = context
cc5e49 1173             context.wascontext = True
6fec21 1174         def __call__(self, request):
CM 1175             self.context.request = request
916f88 1176             return result
cc5e49 1177     return DummyTraverser
51c305 1178
e60985 1179 class DummyContext(object):
dbab77 1180     __parent__ = None
7fc6a3 1181     def __init__(self, next=None, name=None):
8b2c67 1182         self.next = next
7fc6a3 1183         self.__name__ = name
51c305 1184
8b2c67 1185     def __getitem__(self, name):
CM 1186         if self.next is None:
e6c2d2 1187             raise KeyError(name)
8b2c67 1188         return self.next
7de404 1189
7fc6a3 1190     def __repr__(self):
CM 1191         return '<DummyContext with name %s at id %s>'%(self.__name__, id(self))
1192
7de404 1193 class DummyRequest:
def68d 1194
38e09d 1195     application_url = 'http://example.com:5432' # app_url never ends with slash
def68d 1196     matchdict = None
CM 1197     matched_route = None
1198
ebcdc7 1199     def __init__(self, environ=None, path_info=text_('/'), toraise=None):
e62e47 1200         if environ is None:
CM 1201             environ = {}
1202         self.environ = environ
def68d 1203         self._set_path_info(path_info)
CM 1204         self.toraise = toraise
1205
1206     def _get_path_info(self):
1207         if self.toraise:
1208             raise self.toraise
1209         return self._path_info
1210
1211     def _set_path_info(self, v):
1212         self._path_info = v
1213
1214     path_info = property(_get_path_info, _set_path_info)
1215         
dfc2b6 1216
6fec21 1217 def _makeRequest(environ=None):
b60bdb 1218     from pyramid.registry import Registry
6fec21 1219     request = DummyRequest()
CM 1220     request.registry = Registry()
1221     return request