Implemented match_captures
Matthias Dietrich [Mon, 17 Oct 2011 16:42:40 +0000 (18:42 +0200)]
With tests, missing docs.

lib/Catalyst/DispatchType/Chained.pm
t/aggregate/live_component_controller_action_chained.t
t/lib/TestApp/ActionRole/TestMatchCaptures.pm [new file with mode: 0644]
t/lib/TestApp/Controller/Action/Chained.pm

index 2437698..13453df 100644 (file)
@@ -211,6 +211,9 @@ sub recurse_match {
                 # strip CaptureArgs into list
                 push(@captures, splice(@parts, 0, $capture_attr->[0]));
 
+                # check if the action may fit, depending on a given test by the app
+                if ($action->can('match_captures')) { next TRY_ACTION unless $action->match_captures($c, \@captures) }
+
                 # try the remaining parts against children of this action
                 my ($actions, $captures, $action_parts, $n_pathparts) = $self->recurse_match(
                                              $c, '/'.$action->reverse, \@parts
index efea301..6f01812 100644 (file)
@@ -1113,6 +1113,19 @@ sub run_tests {
         ok( index($content, $path) > 1, 'uri can round trip through uri_for' )
             or diag("Expected $path, got $content");
     }
+
+    #
+    #   match_captures
+    #
+    {
+
+        ok( my $response = request('http://localhost/chained/match_captures/foo/bar'), 'match_captures: falling through' );
+        is($response->header('X-TestAppActionTestMatchCaptures'), 'fallthrough', 'match_captures: fell through');
+
+        ok($response = request('http://localhost/chained/match_captures/force/bar'), 'match_captures: *not* falling through' );
+        is($response->header('X-TestAppActionTestMatchCaptures'), 'forcing', 'match_captures: forced');
+        is($response->header('X-TestAppActionTestMatchCapturesHasRan'), 'yes', 'match_captures: actually ran');
+    }
 }
 
 done_testing;
diff --git a/t/lib/TestApp/ActionRole/TestMatchCaptures.pm b/t/lib/TestApp/ActionRole/TestMatchCaptures.pm
new file mode 100644 (file)
index 0000000..3695ffe
--- /dev/null
@@ -0,0 +1,17 @@
+package TestApp::ActionRole::TestMatchCaptures;
+
+use Moose::Role;
+use namespace::autoclean;
+
+sub match_captures {
+    my ($self, $c, $cap) = @_;
+    if ($cap->[0] eq 'force') {
+        $c->res->header( 'X-TestAppActionTestMatchCaptures', 'forcing' );
+        return 1;
+    } else {
+        $c->res->header( 'X-TestAppActionTestMatchCaptures', 'fallthrough' );
+        return 0;
+    }
+}
+
+1;
\ No newline at end of file
index a393e77..cffd3d6 100644 (file)
@@ -5,7 +5,7 @@ use warnings;
 
 use HTML::Entities;
 
-use base qw/Catalyst::Controller/;
+use base qw/Catalyst::Controller::ActionRole/;
 
 sub begin :Private { }
 
@@ -220,6 +220,13 @@ sub roundtrip_urifor_end : Chained('roundtrip_urifor') PathPart('') Args(1) {
     $c->stash->{no_end} = 1;
 }
 
+sub match_captures : Chained('/') PathPart('chained/match_captures') CaptureArgs(1) Does('~TestMatchCaptures') {
+    my ($self, $c) = @_;
+    $c->res->header( 'X-TestAppActionTestMatchCapturesHasRan', 'yes');
+}
+
+sub match_captures_end : Chained('match_captures') PathPart('bar') Args(0) { }
+
 sub end :Private {
   my ($self, $c) = @_;
   return if $c->stash->{no_end};