diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-06-22 04:59:31 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-06-22 04:59:31 +0000 |
| commit | 7fc6a3c63676637018c922e6f997b174639466f0 (patch) | |
| tree | 9dc0fd27543e098bc27e8b47b9a176835976b27a | |
| parent | d70fd93e4b76369edea80ac1ded9da9ac0a93289 (diff) | |
| download | pyramid-7fc6a3c63676637018c922e6f997b174639466f0.tar.gz pyramid-7fc6a3c63676637018c922e6f997b174639466f0.tar.bz2 pyramid-7fc6a3c63676637018c922e6f997b174639466f0.zip | |
We weren't computing the virtual root correctly in a corner case.
| -rw-r--r-- | repoze/bfg/tests/test_traversal.py | 53 | ||||
| -rw-r--r-- | repoze/bfg/traversal.py | 63 |
2 files changed, 74 insertions, 42 deletions
diff --git a/repoze/bfg/tests/test_traversal.py b/repoze/bfg/tests/test_traversal.py index da52ab968..7d24cb9bc 100644 --- a/repoze/bfg/tests/test_traversal.py +++ b/repoze/bfg/tests/test_traversal.py @@ -88,6 +88,7 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) @@ -99,6 +100,7 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ('bar',)) self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) @@ -111,6 +113,7 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) @@ -124,6 +127,7 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], 'bar') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (u'foo',)) + self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) @@ -137,6 +141,7 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], 'bar') self.assertEqual(result['subpath'], ('baz', 'buz')) self.assertEqual(result['traversed'], (u'foo',)) + self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) @@ -150,38 +155,41 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) def test_call_with_vh_root(self): environ = self._getEnviron(PATH_INFO='/baz', HTTP_X_VHM_ROOT='/foo/bar') - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) + baz = DummyContext(None, 'baz') + bar = DummyContext(baz, 'bar') + foo = DummyContext(bar, 'foo') + root = DummyContext(foo, 'root') policy = self._makeOne(root) result = policy(environ) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) + self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], bar) self.assertEqual(result['virtual_root_path'], (u'foo', u'bar')) def test_call_with_vh_root2(self): environ = self._getEnviron(PATH_INFO='/bar/baz', HTTP_X_VHM_ROOT='/foo') - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) + baz = DummyContext(None, 'baz') + bar = DummyContext(baz, 'bar') + foo = DummyContext(bar, 'foo') + root = DummyContext(foo, 'root') policy = self._makeOne(root) result = policy(environ) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) + self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], foo) self.assertEqual(result['virtual_root_path'], (u'foo',)) @@ -198,9 +206,27 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) + self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) + def test_call_with_vh_root4(self): + environ = self._getEnviron(PATH_INFO='/', + HTTP_X_VHM_ROOT='/foo/bar/baz') + baz = DummyContext(None, 'baz') + bar = DummyContext(baz, 'bar') + foo = DummyContext(bar, 'foo') + root = DummyContext(foo, 'root') + policy = self._makeOne(root) + result = policy(environ) + self.assertEqual(result['context'], baz) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], (u'foo', u'bar', u'baz')) + self.assertEqual(result['root'], root) + self.assertEqual(result['virtual_root'], baz) + self.assertEqual(result['virtual_root_path'], (u'foo', u'bar', u'baz')) + def test_call_with_vh_root_path_root(self): policy = self._makeOne(None) environ = self._getEnviron(HTTP_X_VHM_ROOT='/', @@ -210,6 +236,7 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) @@ -239,6 +266,7 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], model) self.assertEqual(result['virtual_root'], model) self.assertEqual(result['virtual_root_path'], ()) @@ -251,6 +279,7 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ('a', 'b','c')) self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], model) self.assertEqual(result['virtual_root'], model) self.assertEqual(result['virtual_root_path'], ()) @@ -263,6 +292,7 @@ class ModelGraphTraverserTests(unittest.TestCase): self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ('bar',)) self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], model) self.assertEqual(result['virtual_root'], model) self.assertEqual(result['virtual_root_path'], ()) @@ -917,15 +947,18 @@ def make_traverser(result): class DummyContext(object): __parent__ = None - __name__ = None - def __init__(self, next=None): + def __init__(self, next=None, name=None): self.next = next + self.__name__ = name def __getitem__(self, name): if self.next is None: raise KeyError, name return self.next + def __repr__(self): + return '<DummyContext with name %s at id %s>'%(self.__name__, id(self)) + class DummyRequest: application_url = 'http://example.com:5432' # app_url never ends with slash def __init__(self, environ=None): diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py index 59ad9115d..2b9a0e611 100644 --- a/repoze/bfg/traversal.py +++ b/repoze/bfg/traversal.py @@ -502,69 +502,68 @@ class ModelGraphTraverser(object): # this request did not match a Routes route subpath = () try: - path = environ['PATH_INFO'] + path = environ['PATH_INFO'] or '/' except KeyError: path = '/' try: - vroot_path_string = environ[VH_ROOT_KEY] + vroot_path = environ[VH_ROOT_KEY] except KeyError: - vroot_path = () - vroot_idx = 0 + vroot_tuple = () + vpath = path + vroot_idx = -1 else: - vroot_path = traversal_path(vroot_path_string) - vroot_idx = len(vroot_path) - path = vroot_path_string + path + vroot_tuple = traversal_path(vroot_path) + vpath = vroot_path + path + vroot_idx = len(vroot_tuple) -1 ob = vroot = self.root - if (not path) or path == '/': - # save a call to traversal_path if we know it's going to return - # the empty tuple - path = () + if vpath == '/' or (not vpath): + # prevent a call to traversal_path if we know it's going + # to return the empty tuple + vpath_tuple = () else: - path = traversal_path(path) - - # in case you're wondering, we do dead reckoning here instead - # of pushing and popping temporary lists for speed purposes - - i = 1 - j = vroot_idx - - for segment in path: + # we do dead reckoning here via tuple slicing instead of + # pushing and popping temporary lists for speed purposes + # and this hurts readability; apologies + i = 0 + vpath_tuple = traversal_path(vpath) + for segment in vpath_tuple: if segment[:2] =='@@': return dict(context=ob, view_name=segment[2:], - subpath=path[i:], traversed=path[:j], + subpath=vpath_tuple[i+1:], + traversed=vpath_tuple[:vroot_idx+i+1], virtual_root=vroot, - virtual_root_path=vroot_path, + virtual_root_path=vroot_tuple, root=self.root) try: getitem = ob.__getitem__ except AttributeError: return dict(context=ob, view_name=segment, - subpath=path[i:], traversed=path[:j], + subpath=vpath_tuple[i+1:], + traversed=vpath_tuple[:vroot_idx+i+1], virtual_root=vroot, - virtual_root_path=vroot_path, + virtual_root_path=vroot_tuple, root=self.root) try: next = getitem(segment) except KeyError: return dict(context=ob, view_name=segment, - subpath=path[i:], traversed=path[:j], + subpath=vpath_tuple[i+1:], + traversed=vpath_tuple[:vroot_idx+i+1], virtual_root=vroot, - virtual_root_path=vroot_path, + virtual_root_path=vroot_tuple, root=self.root) - - if vroot_idx == i-1: - vroot = ob + if i == vroot_idx: + vroot = next ob = next i += 1 - j += 1 return dict(context=ob, view_name=u'', subpath=subpath, - traversed=path, virtual_root=vroot, - virtual_root_path=vroot_path, root=self.root) + traversed=vpath_tuple, virtual_root=vroot, + virtual_root_path=vroot_tuple, root=self.root) class TraversalContextURL(object): """ The IContextURL adapter used to generate URLs for a context |
