Commits

percious  committed d05b03f

better testing for self-calling lookups.

  • Participants
  • Parent commits 0fefcad

Comments (0)

Files changed (2)

File tg/controllers/dispatcher.py

 
         remainder = list(remainder[:])
         for i, controller in enumerate(reversed(state.controller_path.values())):
-#            print i, controller, remainder
             if self._is_exposed(controller, '_lookup'):
                 new_controller, new_remainder = controller._lookup(*remainder)
                 last_tried_lookup = getattr(current_controller, '_last_tried_lookup', None)
-                if last_tried_lookup.__class__.__name__ != new_controller.__class__.__name__:
-#                    import ipdb; ipdb.set_trace();
+                if last_tried_lookup.__class__.__name__ != new_controller.__class__.__name__ or remainder != new_remainder:
                     new_controller._last_tried_lookup = new_controller
                     state.add_controller(new_controller.__class__.__name__, new_controller)
                     dispatcher = getattr(new_controller, '_dispatch', self._dispatch)
                 warn('lookup method is deprecated, please replace with _lookup', DeprecationWarning)
                 new_controller, new_remainder = controller.lookup(*remainder)
                 last_tried_lookup = getattr(current_controller, '_last_tried_lookup', None)
-                if type(last_tried_lookup) != type(new_controller):
-                    self._last_tried_lookup = new_controller
+                if last_tried_lookup.__class__.__name__ != new_controller.__class__.__name__ or remainder != new_remainder:
+                    new_controller._last_tried_lookup = new_controller
                     state.add_controller(new_controller.__class__.__name__, new_controller)
                     dispatcher = getattr(new_controller, '_dispatch', self._dispatch)
                     return dispatcher(state, new_remainder)
                 state.dispatcher = self
                 return state
 
-#            if self._is_exposed(controller, 'index') and\
-#               method_matches_args(controller.index, state.params, remainder, self._use_lax_params):
-#                state.add_method(controller.index, remainder)
-#                state.dispatcher = self
-#                return state
             try:
                 remainder.insert(0, state.url_path[-(i+orig_remainder_len+1)])
             except IndexError:
 
         raise HTTPNotFound
 
-        orig_url_path = state.url_path
-        if remainder:
-            state.url_path = state.url_path[:-len(remainder)]
-        for i in xrange(len(state.controller_path)):
-            controller = state.controller
-            if self._is_exposed(controller, '_default'):
-                state.add_method(controller._default, remainder)
-                state.dispatcher = self
-                return state
-            if self._is_exposed(controller, '_lookup'):
-                new_controller, new_remainder = controller._lookup(*remainder)
-                last_tried_lookup = getattr(self, '_last_tried_lookup', None)
-                if type(last_tried_lookup) != type(new_controller):
-                    #prevents infinite recursion
-                    new_controller._last_tried_lookup = new_controller
-                    state.add_controller(remainder[0], new_controller)
-                    dispatcher = getattr(new_controller, '_dispatch', self._dispatch)
-                        
-                    return dispatcher(state, new_remainder)
-
-            if self._is_exposed(controller, 'default'):
-                warn('default method is deprecated, please replace with _default', DeprecationWarning)
-                state.add_method(controller.default, remainder)
-                state.dispatcher = self
-                return state
-            if self._is_exposed(controller, 'lookup'):
-                warn('lookup method is deprecated, please replace with _lookup', DeprecationWarning)
-                controller, remainder = controller.lookup(*remainder)
-                state.url_path = '/'.join(remainder)
-                return self._dispatch_controller(
-                    'lookup', controller, state, remainder)
-            state.controller_path.pop()
-            if len(state.url_path):
-                remainder = list(remainder)
-                remainder.insert(0, state.url_path[-1])
-                state.url_path.pop()
-        raise HTTPNotFound
-
     def _dispatch(self, state, remainder):
         """
         This method defines how the object dispatch mechanism works, including

File tg/tests/test_tg_controller_dispatch.py

     @expose()
     def index(self):
         return "first controller with index"
+    
 
 class RemoteErrorHandler(TGController):
     @expose()
 class SubController5:
     default_with_args = DefaultWithArgsAndValidatorsController()
 
+class HelperWithSpecificArgs(TGController):
+    
+    @expose()
+    def index(self, **kw):
+        return str(kw)
+
+    @expose()
+    def method(self, arg1, arg2, **kw):
+        return str((arg1, arg2, kw))
+    
+class SelfCallingLookupController(TGController):
+
+    @expose()
+    def _lookup(self, a, *args):
+        if a in ['a', 'b', 'c']:
+            return SelfCallingLookupController(), args
+        a = [a]
+        a.extend(args)
+        return HelperWithSpecificArgs(), a
+    
+    @expose()
+    def index(self, *args, **kw):
+        return str((args, kw))
+
 class BasicTGController(TGController):
     mounted_app = WSGIAppController(wsgi_app)
 
 
     lookup = LookupController()
     lookup_with_args = LookupControllerWithArgs()
+    self_calling = SelfCallingLookupController()
 
     @expose(content_type='application/rss+xml')
     def ticket2351(self, **kw):
     def test_embedded_lookup_with_index_method(self):
         resp = self.app.get('/embedded_lookup_with_index/a/b/method')
         assert 'helper method' in resp, resp
-        
+    
+    def test_self_calling_lookup_simple_index(self):
+        resp = self.app.get('/self_calling')
+        assert '((), {})' in resp, resp
+
+    def test_self_calling_lookup_method(self):
+        resp = self.app.get('/self_calling/a/method/a/b')
+        assert "('a', 'b', {})" in resp, resp
+
+    def test_self_calling_lookup_multiple_calls_method(self):
+        resp = self.app.get('/self_calling/a/b/c/method/a/b')
+        assert "('a', 'b', {})" in resp, resp