added ActionClass attribute
Matt S Trout [Fri, 19 May 2006 12:55:14 +0000 (12:55 +0000)]
Changes
lib/Catalyst/Base.pm
t/lib/Catalyst/Action/TestAfter.pm [new file with mode: 0644]
t/lib/Catalyst/Action/TestBefore.pm [new file with mode: 0644]
t/lib/TestApp/Action/TestBefore.pm [new file with mode: 0644]
t/lib/TestApp/Controller/Action/Action.pm [new file with mode: 0644]
t/live_component_controller_action_action.t [new file with mode: 0644]

diff --git a/Changes b/Changes
index b3d9216..816d673 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,6 @@
 This file documents the revision history for Perl extension Catalyst.
 
+        - Added ActionClass attribute
         - Removed Test::WWW::Mechanize::Catalyst from Makefile.PL (circular dep)
         - Updated docs for Catalyst::Component
         - Separated execute and dispatch on Catalyst::Action
index ea2063a..1ddbe8f 100644 (file)
@@ -151,7 +151,18 @@ sub register_actions {
 
 sub create_action {
     my $self = shift;
-    $self->_action_class->new( { @_ } );
+    my %args = @_;
+
+    my $class = (exists $args{attributes}{ActionClass}
+                    ? $args{attributes}{ActionClass}[0]
+                    : $self->_action_class);
+
+    unless ( $class->can("can") ) {
+      $class->require;
+      die "Couldn't load action class ${class}: $@" if $@;
+    }
+    
+    return $class->new( \%args );
 }
 
 sub _parse_attrs {
@@ -220,6 +231,14 @@ sub _parse_LocalRegex_attr {
 
 sub _parse_LocalRegexp_attr { shift->_parse_LocalRegex_attr(@_); }
 
+sub _parse_ActionClass_attr {
+    my ( $self, $c, $name, $value ) = @_;
+    unless ( $value =~ s/^\+// ) {
+      $value = join('::', $self->_action_class, $value );
+    }
+    return ( 'ActionClass', $value );
+}
+
 =head1 SEE ALSO
 
 L<Catalyst>, L<Catalyst::Controller>.
diff --git a/t/lib/Catalyst/Action/TestAfter.pm b/t/lib/Catalyst/Action/TestAfter.pm
new file mode 100644 (file)
index 0000000..61fb9d7
--- /dev/null
@@ -0,0 +1,15 @@
+package Catalyst::Action::TestAfter;
+
+use strict;
+use warnings;
+
+use base qw/Catalyst::Action/;
+
+sub execute {
+    my $self = shift;
+    my ( $controller, $c ) = @_;
+    $self->NEXT::execute( @_ );
+    $c->res->header( 'X-Action-After', $c->stash->{after_message} );
+}
+
+1;
diff --git a/t/lib/Catalyst/Action/TestBefore.pm b/t/lib/Catalyst/Action/TestBefore.pm
new file mode 100644 (file)
index 0000000..8bc2e64
--- /dev/null
@@ -0,0 +1,15 @@
+package Catalyst::Action::TestBefore;
+
+use strict;
+use warnings;
+
+use base qw/Catalyst::Action/;
+
+sub execute {
+    my $self = shift;
+    my ( $controller, $c ) = @_;
+    $c->stash->{test} = 'works';
+    $self->NEXT::execute( @_ );
+}
+
+1;
diff --git a/t/lib/TestApp/Action/TestBefore.pm b/t/lib/TestApp/Action/TestBefore.pm
new file mode 100644 (file)
index 0000000..0d802bf
--- /dev/null
@@ -0,0 +1,15 @@
+package TestApp::Action::TestBefore;
+
+use strict;
+use warnings;
+
+use base qw/Catalyst::Action/;
+
+sub execute {
+    my $self = shift;
+    my ( $controller, $c, $test ) = @_;
+    $c->res->header( 'X-TestAppActionTestBefore', $test );
+    $self->NEXT::execute( @_ );
+}
+
+1;
diff --git a/t/lib/TestApp/Controller/Action/Action.pm b/t/lib/TestApp/Controller/Action/Action.pm
new file mode 100644 (file)
index 0000000..9532a69
--- /dev/null
@@ -0,0 +1,23 @@
+package TestApp::Controller::Action::Action;
+
+use strict;
+use base 'TestApp::Controller::Action';
+
+sub action_action_one : Global : ActionClass('TestBefore') {
+    my ( $self, $c ) = @_;
+    $c->res->header( 'X-Action', $c->stash->{test} );
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+sub action_action_two : Global : ActionClass('TestAfter') {
+    my ( $self, $c ) = @_;
+    $c->stash->{after_message} = 'awesome';
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+sub action_action_three : Global : ActionClass('+TestApp::Action::TestBefore') {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+1;
diff --git a/t/live_component_controller_action_action.t b/t/live_component_controller_action_action.t
new file mode 100644 (file)
index 0000000..f82a250
--- /dev/null
@@ -0,0 +1,90 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 2; }
+
+use Test::More tests => 21 * $iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        ok( my $response = request('http://localhost/action_action_one'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_action_one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Action',
+            'Test Class'
+        );
+        is( $response->header('X-Action'), 'works' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action_action_two'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_action_two', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Action',
+            'Test Class'
+        );
+        is( $response->header('X-Action-After'), 'awesome' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action_action_three/one/two'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_action_three', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Action',
+            'Test Class'
+        );
+        is( $response->header('X-TestAppActionTestBefore'), 'one' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+}