[Catalyst-commits] r9567 - in Catalyst-Runtime/5.70/trunk: . lib lib/Catalyst t t/lib t/lib/TestApp/Controller/Action

t0m at dev.catalyst.perl.org t0m at dev.catalyst.perl.org
Mon Mar 23 23:53:48 GMT 2009


Author: t0m
Date: 2009-03-23 23:53:47 +0000 (Mon, 23 Mar 2009)
New Revision: 9567

Modified:
   Catalyst-Runtime/5.70/trunk/Changes
   Catalyst-Runtime/5.70/trunk/lib/Catalyst.pm
   Catalyst-Runtime/5.70/trunk/lib/Catalyst/Dispatcher.pm
   Catalyst-Runtime/5.70/trunk/t/lib/TestApp.pm
   Catalyst-Runtime/5.70/trunk/t/lib/TestApp/Controller/Action/Go.pm
   Catalyst-Runtime/5.70/trunk/t/lib/TestApp/Controller/Action/Visit.pm
   Catalyst-Runtime/5.70/trunk/t/live_component_controller_action_go.t
   Catalyst-Runtime/5.70/trunk/t/live_component_controller_action_visit.t
Log:
svn diff -r 9551:9552 http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/trunk/ (kinda)
Fixup Visit for chained - backport where branch was merged to 5.80 trunk, applied cleanly sans test renames (t0m)

Modified: Catalyst-Runtime/5.70/trunk/Changes
===================================================================
--- Catalyst-Runtime/5.70/trunk/Changes	2009-03-23 23:29:02 UTC (rev 9566)
+++ Catalyst-Runtime/5.70/trunk/Changes	2009-03-23 23:53:47 UTC (rev 9567)
@@ -1,11 +1,16 @@
 # This file documents the revision history for Perl extension Catalyst.
 
 5.71000_01 UNRELEASED
-        - Add failing test for passing arguments to visited chained 
-          actions (Radoslaw Zielinski)
         - Support Moose components so that attribute defaults work
           and BUILD methods are correctly called (t0m)
           - Add tests for this (Florian Ragwitz)
+        - Change the $c->visit and $c->go methods to optionally take
+          CaptureArgs, making them useful to call ActionChains with (t0m)
+          - Tests for this (Radoslaw Zielinski)
+        - Fix _invoke_as_component method to find the proper action instance
+          for dispatchable actions so that ->visit or ->going to ActionChains
+          with qw/Class::Name method_name/ works correctly (t0m)
+          - Tests for this (Radoslaw Zielinski)
         - Added Catalyst::Test::ctx_request to be able to inspect
           the context object after a request is made (Jos Boumans)
 

Modified: Catalyst-Runtime/5.70/trunk/lib/Catalyst/Dispatcher.pm
===================================================================
--- Catalyst-Runtime/5.70/trunk/lib/Catalyst/Dispatcher.pm	2009-03-23 23:29:02 UTC (rev 9566)
+++ Catalyst-Runtime/5.70/trunk/lib/Catalyst/Dispatcher.pm	2009-03-23 23:53:47 UTC (rev 9567)
@@ -12,7 +12,7 @@
 use Text::SimpleTable;
 use Tree::Simple;
 use Tree::Simple::Visitor::FindByPath;
-use Scalar::Util ();
+use Scalar::Util qw(blessed);
 
 # Stringify to class
 use overload '""' => sub { return ref shift }, fallback => 1;
@@ -129,7 +129,8 @@
 }
 
 # $self->_command2action( $c, $command [, \@arguments ] )
-# Search for an action, from the command and returns C<($action, $args)> on
+# $self->_command2action( $c, $command [, \@captures, \@arguments ] )
+# Search for an action, from the command and returns C<($action, $args, $captures)> on
 # success. Returns C<(0)> on error.
 
 sub _command2action {
@@ -140,8 +141,12 @@
         return 0;
     }
 
-    my @args;
+    my (@args, @captures);
     
+    if ( ref( $extra_params[-2] ) eq 'ARRAY' ) {
+        @captures = @{ pop @extra_params };
+    }
+
     if ( ref( $extra_params[-1] ) eq 'ARRAY' ) {
         @args = @{ pop @extra_params }
     } else {
@@ -168,7 +173,7 @@
         $action = $self->_invoke_as_component( $c, $command, $method );
     }
 
-    return $action, \@args;
+    return $action, \@args, \@captures;
 }
 
 =head2 $self->visit( $c, $command [, \@arguments ] )
@@ -186,7 +191,7 @@
     my $self = shift;
     my $opname = shift;
     my ( $c, $command ) = @_;
-    my ( $action, $args ) = $self->_command2action(@_);
+    my ( $action, $args, $captures ) = $self->_command2action(@_);
     my $error = qq/Couldn't $opname("$command"): /;
 
     if (!$action) {
@@ -195,7 +200,7 @@
     }
     elsif (!defined $action->namespace) {
         $error .= qq/Action has no namespace: cannot $opname() to a plain /
-                 .qq/method or component, must be a :Action or some sort./
+                 .qq/method or component, must be an :Action of some sort./
     }
     elsif (!$action->class->can('_DISPATCH')) {
         $error .= qq/Action cannot _DISPATCH. /
@@ -214,6 +219,7 @@
     $action = $self->expand_action($action);
 
     local $c->request->{arguments} = $args;
+    local $c->request->{captures}  = $captures;
     local $c->{namespace} = $action->{'namespace'};
     local $c->{action} = $action;
 
@@ -241,7 +247,7 @@
 sub forward {
     my $self = shift;
     my ( $c, $command ) = @_;
-    my ( $action, $args ) = $self->_command2action(@_);
+    my ( $action, $args, $captures ) = $self->_command2action(@_);
 
     unless ($action) {
         my $error =
@@ -292,35 +298,44 @@
     }
 }
 
-sub _find_component_class {
+sub _find_component {
     my ( $self, $c, $component ) = @_;
 
-    return ref($component)
-      || ref( $c->component($component) )
-      || $c->component($component);
+    # fugly, why doesn't ->component('MyApp') work?
+    return $c if ($component eq blessed($c));
+
+    return blessed($component)
+        ? $component
+        : $c->component($component);
 }
 
 sub _invoke_as_component {
-    my ( $self, $c, $component, $method ) = @_;
+    my ( $self, $c, $component_or_class, $method ) = @_;
 
-    my $class = $self->_find_component_class( $c, $component ) || return 0;
+    my $component = $self->_find_component($c, $component_or_class);
+    my $component_class = blessed $component || return 0;
 
-    if ( my $code = $class->can($method) ) {
+    if (my $code = $component_class->can('action_for')) {
+        my $possible_action = $component->$code($method);
+        return $possible_action if $possible_action;
+    }
+
+    if ( my $code = $component_class->can($method) ) {
         return $self->method_action_class->new(
             {
                 name      => $method,
                 code      => $code,
-                reverse   => "$class->$method",
-                class     => $class,
+                reverse   => "$component_class->$method",
+                class     => $component_class,
                 namespace => Catalyst::Utils::class2prefix(
-                    $class, $c->config->{case_sensitive}
+                    $component_class, $c->config->{case_sensitive}
                 ),
             }
         );
     }
     else {
         my $error =
-          qq/Couldn't forward to "$class". Does not implement "$method"/;
+          qq/Couldn't forward to "$component_class". Does not implement "$method"/;
         $c->error($error);
         $c->log->debug($error)
           if $c->debug;

Modified: Catalyst-Runtime/5.70/trunk/lib/Catalyst.pm
===================================================================
--- Catalyst-Runtime/5.70/trunk/lib/Catalyst.pm	2009-03-23 23:29:02 UTC (rev 9566)
+++ Catalyst-Runtime/5.70/trunk/lib/Catalyst.pm	2009-03-23 23:53:47 UTC (rev 9567)
@@ -328,9 +328,9 @@
 
 sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
 
-=head2 $c->visit( $action [, \@arguments ] )
+=head2 $c->visit( $action [, \@captures, \@arguments ] )
 
-=head2 $c->visit( $class, $method, [, \@arguments ] )
+=head2 $c->visit( $class, $method, [, \@captures, \@arguments ] )
 
 Almost the same as C<forward>, but does a full dispatch, instead of just
 calling the new C<$action> / C<$class-E<gt>$method>. This means that C<begin>,
@@ -354,9 +354,9 @@
 
 sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
 
-=head2 $c->go( $action [, \@arguments ] )
+=head2 $c->go( $action [, \@captures, \@arguments ] )
 
-=head2 $c->go( $class, $method, [, \@arguments ] )
+=head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
 
 Almost the same as C<detach>, but does a full dispatch like C<visit>,
 instead of just calling the new C<$action> /

Modified: Catalyst-Runtime/5.70/trunk/t/lib/TestApp/Controller/Action/Go.pm
===================================================================
--- Catalyst-Runtime/5.70/trunk/t/lib/TestApp/Controller/Action/Go.pm	2009-03-23 23:29:02 UTC (rev 9566)
+++ Catalyst-Runtime/5.70/trunk/t/lib/TestApp/Controller/Action/Go.pm	2009-03-23 23:53:47 UTC (rev 9567)
@@ -63,7 +63,7 @@
 
 sub go_chained : Local {
     my ( $self, $c, $val ) = @_;
-    $c->go('/action/chained/foo/spoon',[1]);
+    $c->go('/action/chained/foo/spoon', ['captureme'], [qw/arg1 arg2/]);
 }
 
 sub view : Local {
@@ -96,7 +96,7 @@
 
 sub class_go_test_action : Local {
     my ( $self, $c ) = @_;
-    $c->go(qw/TestApp class_go_test_method/);
+    $c->go(qw/TestApp/);
 }
 
 1;

Modified: Catalyst-Runtime/5.70/trunk/t/lib/TestApp/Controller/Action/Visit.pm
===================================================================
--- Catalyst-Runtime/5.70/trunk/t/lib/TestApp/Controller/Action/Visit.pm	2009-03-23 23:29:02 UTC (rev 9566)
+++ Catalyst-Runtime/5.70/trunk/t/lib/TestApp/Controller/Action/Visit.pm	2009-03-23 23:53:47 UTC (rev 9567)
@@ -61,10 +61,11 @@
 }
 
 sub visit_chained : Local {
-    my ( $self, $c, $val ) = @_;
-      $val eq 1 ? $c->visit( '/action/chained/foo/spoon',                                 [$val] )
-    : $val eq 2 ? $c->visit( qw/ Action::Chained::Foo spoon /,                            [$val] )
-    :             $c->visit( $c->controller('Action::Chained::Foo')->action_for('spoon'), [$val] )
+    my ( $self, $c, $val, $capture, @args ) = @_;
+    my @cap_and_args = ([$capture], [@args]);
+      $val eq 1 ? $c->visit( '/action/chained/foo/spoon',                                 @cap_and_args)
+    : $val eq 2 ? $c->visit( qw/ Action::Chained::Foo spoon /,                            @cap_and_args)
+    :             $c->visit( $c->controller('Action::Chained::Foo')->action_for('spoon'), @cap_and_args)
 }
 
 sub view : Local {
@@ -97,7 +98,7 @@
 
 sub class_visit_test_action : Local {
     my ( $self, $c ) = @_;
-    $c->visit(qw/TestApp class_visit_test_method/);
+    $c->visit(qw/TestApp/);
 }
 
 1;

Modified: Catalyst-Runtime/5.70/trunk/t/lib/TestApp.pm
===================================================================
--- Catalyst-Runtime/5.70/trunk/t/lib/TestApp.pm	2009-03-23 23:29:02 UTC (rev 9566)
+++ Catalyst-Runtime/5.70/trunk/t/lib/TestApp.pm	2009-03-23 23:53:47 UTC (rev 9567)
@@ -76,16 +76,6 @@
     $c->response->headers->header( 'X-Class-Forward-Test-Method' => 1 );
 }
 
-sub class_go_test_method :Private {
-    my ( $self, $c ) = @_;
-    $c->response->headers->header( 'X-Class-Go-Test-Method' => 1 );
-}
-
-sub class_visit_test_method :Private {
-    my ( $self, $c ) = @_;
-    $c->response->headers->header( 'X-Class-Visit-Test-Method' => 1 );
-}
-
 sub loop_test : Local {
     my ( $self, $c ) = @_;
 

Modified: Catalyst-Runtime/5.70/trunk/t/live_component_controller_action_go.t
===================================================================
--- Catalyst-Runtime/5.70/trunk/t/live_component_controller_action_go.t	2009-03-23 23:29:02 UTC (rev 9566)
+++ Catalyst-Runtime/5.70/trunk/t/live_component_controller_action_go.t	2009-03-23 23:53:47 UTC (rev 9567)
@@ -242,7 +242,7 @@
         );
         ok( !$response->is_success, 'Response Fails' );
         is( $response->content,
-            q(FATAL ERROR: Couldn't go("TestApp"): Action has no namespace: cannot go() to a plain method or component, must be a :Action or some sort.),
+            q(FATAL ERROR: Couldn't go("TestApp"): Action has no namespace: cannot go() to a plain method or component, must be an :Action of some sort.),
             'Error message'
         );
     }
@@ -262,7 +262,7 @@
         ok( my $response = request('http://localhost/action/go/go_chained'), 'go to chained + subcontroller endpoint' );
         is( $response->header('X-Catalyst-Executed'),
             $expected, 'Executed actions' );
-        is( $response->content, '; 1', 'Content OK' );
+        is( $response->content, 'arg1, arg2; captureme', 'Content OK' );
     }
 
 }

Modified: Catalyst-Runtime/5.70/trunk/t/live_component_controller_action_visit.t
===================================================================
--- Catalyst-Runtime/5.70/trunk/t/live_component_controller_action_visit.t	2009-03-23 23:29:02 UTC (rev 9566)
+++ Catalyst-Runtime/5.70/trunk/t/live_component_controller_action_visit.t	2009-03-23 23:53:47 UTC (rev 9567)
@@ -253,7 +253,7 @@
         );
         ok( !$response->is_success, 'Response Fails' );
         is( $response->content,
-            q[FATAL ERROR: Couldn't visit("TestApp"): Action has no namespace: cannot visit() to a plain method or component, must be a :Action or some sort.],
+            q{FATAL ERROR: Couldn't visit("TestApp"): Action has no namespace: cannot visit() to a plain method or component, must be an :Action of some sort.},
             "Cannot visit app namespace"
         );
     }
@@ -272,11 +272,12 @@
         my $expected = join( ", ", @expected );
 
         for my $i ( 1..3 ) {
-            ok( my $response = request("http://localhost/action/visit/visit_chained/$i"),
+            ok( my $response = request("http://localhost/action/visit/visit_chained/$i/becomescapture/arg1/arg2"),
                 "visit to chained + subcontroller endpoint for $i" );
             is( $response->header('X-Catalyst-Executed'),
                 $expected, "Executed actions for $i" );
-            is( $response->content, "; $i", "Content OK for $i" );
+            is( $response->content, "arg1, arg2; becomescapture",
+                "Content OK for $i" );
         }
     }
 




More information about the Catalyst-commits mailing list