[Catalyst-commits] r13640 - in Catalyst-Engine-Apache/trunk: . lib/Catalyst/Engine lib/Catalyst/Engine/Apache lib/Catalyst/Engine/Apache2 t t/lib t/lib/TestApp/Controller/Action t/optional xt xt/author

rafl at dev.catalyst.perl.org rafl at dev.catalyst.perl.org
Mon Oct 4 22:34:18 GMT 2010


Author: rafl
Date: 2010-10-04 23:34:18 +0100 (Mon, 04 Oct 2010)
New Revision: 13640

Added:
   Catalyst-Engine-Apache/trunk/.gitignore
   Catalyst-Engine-Apache/trunk/dist.ini
   Catalyst-Engine-Apache/trunk/xt/
   Catalyst-Engine-Apache/trunk/xt/author/
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_action.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_auto.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_begin.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_chained.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_default.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_detach.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_end.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_forward.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_global.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_index.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_inheritance.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_local.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_multipath.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_path.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_private.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_regexp.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_streaming.t
   Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_args.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_body.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_body_demand.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_cookies.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_headers.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_parameters.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_uploads.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_uri.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_cookies.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_errors.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_headers.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_large.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_redirect.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_status.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_setup_basics.t
   Catalyst-Engine-Apache/trunk/xt/author/live_engine_setup_plugins.t
   Catalyst-Engine-Apache/trunk/xt/author/live_fork.t
   Catalyst-Engine-Apache/trunk/xt/author/live_loop.t
   Catalyst-Engine-Apache/trunk/xt/author/live_plugin_loaded.t
   Catalyst-Engine-Apache/trunk/xt/author/live_priorities.t
   Catalyst-Engine-Apache/trunk/xt/author/live_recursion.t
   Catalyst-Engine-Apache/trunk/xt/author/notabs.t
   Catalyst-Engine-Apache/trunk/xt/author/pod.t
   Catalyst-Engine-Apache/trunk/xt/author/podcoverage.t
Removed:
   Catalyst-Engine-Apache/trunk/MANIFEST.SKIP
   Catalyst-Engine-Apache/trunk/Makefile.PL
   Catalyst-Engine-Apache/trunk/README
   Catalyst-Engine-Apache/trunk/t/author/
Modified:
   Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache.pm
   Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache/MP13.pm
   Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2.pm
   Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2/MP19.pm
   Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2/MP20.pm
   Catalyst-Engine-Apache/trunk/t/00compiles.t
   Catalyst-Engine-Apache/trunk/t/lib/ACLTestApp.pm
   Catalyst-Engine-Apache/trunk/t/lib/TestApp/Controller/Action/Chained.pm
   Catalyst-Engine-Apache/trunk/t/lib/TestApp/Controller/Action/Streaming.pm
   Catalyst-Engine-Apache/trunk/t/optional/mod_perl-locationmatch.pl
   Catalyst-Engine-Apache/trunk/t/optional/mod_perl-non-root.pl
   Catalyst-Engine-Apache/trunk/t/optional/mod_perl.pl
Log:
Convert to dzil

Added: Catalyst-Engine-Apache/trunk/.gitignore
===================================================================
--- Catalyst-Engine-Apache/trunk/.gitignore	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/.gitignore	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,5 @@
+.*
+!.gitignore
+Debian*
+Catalyst-Engine-Apache-*
+.build

Deleted: Catalyst-Engine-Apache/trunk/MANIFEST.SKIP
===================================================================
--- Catalyst-Engine-Apache/trunk/MANIFEST.SKIP	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/MANIFEST.SKIP	2010-10-04 22:34:18 UTC (rev 13640)
@@ -1,39 +0,0 @@
-Catalyst-Engine-Apache-.*
-
-.*\.orig
-.*\.rej
-
-# Avoid version control files.
-\bRCS\b
-\bCVS\b
-,v$
-\B\.svn\b
-
-# Avoid Makemaker generated and utility files.
-\bMakefile$
-\bblib
-\bMakeMaker-\d
-\bpm_to_blib$
-\bblibdirs$
-^MANIFEST\.SKIP$
-
-# Avoid Module::Build generated and utility files.
-\bBuild$
-\b_build
-
-# Avoid temp and backup files.
-~$
-\.tmp$
-\.old$
-\.bak$
-\#$
-\b\.#
-
-# Avoid Apache::Test files
-t/conf/apache_test_config.pm
-t/conf/extra.conf$
-t/conf/httpd.conf
-t/conf/mime.types
-t/conf/modperl
-t/htdocs
-t/logs

Deleted: Catalyst-Engine-Apache/trunk/Makefile.PL
===================================================================
--- Catalyst-Engine-Apache/trunk/Makefile.PL	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/Makefile.PL	2010-10-04 22:34:18 UTC (rev 13640)
@@ -1,25 +0,0 @@
-use strict;
-use warnings;
-use inc::Module::Install 0.91;
-use Module::Install::AuthorRequires;
-use Module::Install::AuthorTests;
-
-name 'Catalyst-Engine-Apache';
-all_from 'lib/Catalyst/Engine/Apache.pm';
-
-requires 'Catalyst::Runtime' => 5.80;
-
-test_requires 'Test::More' => '0.88';
-
-auto_install;
-resources repository => 'http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Engine-Apache/trunk';
-
-author_requires 'Test::NoTabs';
-author_tests 't/author';
-
-if ($Module::Install::AUTHOR) {
-    system("pod2text lib/Catalyst/Engine/Apache.pm > README")
-        and die;
-}
-
-WriteAll;

Deleted: Catalyst-Engine-Apache/trunk/README
===================================================================
--- Catalyst-Engine-Apache/trunk/README	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/README	2010-10-04 22:34:18 UTC (rev 13640)
@@ -1,89 +0,0 @@
-NAME
-    Catalyst::Engine::Apache - Catalyst Apache Engines
-
-SYNOPSIS
-    For example Apache configurations, see the documentation for the engine
-    that corresponds to your Apache version.
-
-    "Catalyst::Engine::Apache::MP13" - mod_perl 1.3x
-
-    "Catalyst::Engine::Apache2::MP19" - mod_perl 1.99x
-
-    "Catalyst::Engine::Apache2::MP20" - mod_perl 2.x
-
-DESCRIPTION
-    These classes provide mod_perl support for Catalyst.
-
-METHODS
-  $c->engine->apache
-    Returns an "Apache", "Apache::RequestRec" or "Apache2::RequestRec"
-    object, depending on your mod_perl version. This method is also
-    available as $c->apache.
-
-  $c->engine->return
-    If you need to return something other than OK from the mod_perl handler,
-    you may set any other Apache constant in this method. You should only
-    use this method if you know what you are doing or bad things may happen!
-    For example, to return DECLINED in mod_perl 2:
-
-        use Apache2::Const -compile => qw(DECLINED);
-        $c->engine->return( Apache2::Const::DECLINED );
-
-  NOTES ABOUT LOCATIONMATCH
-    The Apache engine tries to figure out the correct base path if your app
-    is running within a LocationMatch block. For example:
-
-        <LocationMatch ^/match/(this|that)*>
-            SetHandler          modperl
-            PerlResponseHandler MyApp
-        </LocationMatch>
-
-    This will correctly set the base path to '/match/this/' or
-    '/match/that/' depending on which path was used for the request.
-
-    In some cases this may not be what you want, so you can disable this
-    behavior by adding this to your configuration:
-
-        PerlSetVar CatalystDisableLocationMatch 1
-
-  NOTES ON NON-STANDARD PORTS
-    If you wish to run your site on a non-standard port you will need to use
-    the "Port" Apache config rather than "Listen". This will result in the
-    correct port being added to urls created using "uri_for".
-
-        Port 8080
-
-OVERLOADED METHODS
-    This class overloads some methods from "Catalyst::Engine".
-
-    prepare_request($r)
-    prepare_connection
-    prepare_query_parameters
-    prepare_headers
-    prepare_path
-    read_chunk
-    finalize_body
-    finalize_headers
-    write
-
-SEE ALSO
-    Catalyst Catalyst::Engine.
-
-MAINTAINERS
-    Current maintainer, Tomas Doran (t0m) "<bobtfish at bobtfish.net>".
-
-AUTHORS
-    Sebastian Riedel, "<sri at cpan.org>".
-
-    Christian Hansen, "<ch at ngmedia.com>".
-
-    Andy Grundman, "<andy at hybridized.org>".
-
-COPYRIGHT
-    Copyright 2005-2010 by the above above listed "AUTHORS" and
-    "MAINTAINERS".
-
-LICENSE
-    This program is free software, you can redistribute it and/or modify it
-    under the same terms as Perl itself.
-

Added: Catalyst-Engine-Apache/trunk/dist.ini
===================================================================
--- Catalyst-Engine-Apache/trunk/dist.ini	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/dist.ini	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,20 @@
+name = Catalyst-Engine-Apache
+version = 1.15
+author = Sebastian Riedel <sri at cpan.org>
+author = Christian Hansen <ch at ngmedia.com>
+author = Andy Grundman <andy at hybridized.org>
+author = Tomas Doran <bobtfish at bobtfish.net>
+license = Perl_5
+copyright_holder = The "AUTHORS"
+
+[@Filter]
+-bundle = @FLORA
+-remove = PodCoverageTests
+-remove = EOLTests
+dist = Catalyst-Engine-Apache
+repository_at = catsvn
+authority = cpan:BOBTFISH
+auto_prereqs = 0
+
+[Prereqs]
+Catalyst::Runtime = 5.80

Modified: Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache/MP13.pm
===================================================================
--- Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache/MP13.pm	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache/MP13.pm	2010-10-04 22:34:18 UTC (rev 13640)
@@ -1,4 +1,5 @@
 package Catalyst::Engine::Apache::MP13;
+# ABSTRACT: Catalyst Apache mod_perl 1.3x Engine
 
 use strict;
 use warnings;
@@ -11,11 +12,11 @@
 
 sub finalize_headers {
     my ( $self, $c ) = @_;
-    
+
     $self->SUPER::finalize_headers( $c );
-    
+
     $self->apache->send_http_header;
-    
+
     return 0;
 }
 
@@ -29,44 +30,39 @@
 }
 
 1;
-__END__
 
-=head1 NAME
-
-Catalyst::Engine::Apache::MP13 - Catalyst Apache mod_perl 1.3x Engine
-
 =head1 SYNOPSIS
 
     # Set up your Catalyst app as a mod_perl 1.3x application in httpd.conf
     <Perl>
         use lib qw( /var/www/MyApp/lib );
     </Perl>
-    
+
     # Preload your entire application
     PerlModule MyApp
-    
+
     <VirtualHost *>
         ServerName   myapp.hostname.com
         DocumentRoot /var/www/MyApp/root
-        
+
         <Location />
             SetHandler       perl-script
             PerlHandler      MyApp
         </Location>
-        
+
         # you can also run your app in any non-root location
         <Location /some/other/path>
             SetHandler      perl-script
             PerlHandler     MyApp
         </Location>
-        
+
         # Make sure to let Apache handle your static files
         # (And remember to remove the Static::Simple plugin in production)
         <Location /static>
             SetHandler      default-handler
         </Location>
     </VirtualHost>
-    
+
 =head1 DESCRIPTION
 
 This is the Catalyst engine specialized for Apache mod_perl version 1.3x.
@@ -80,26 +76,26 @@
 
     PerlModule Apache::Registry
     Alias / /var/www/MyApp/script/myapp_registry.pl/
-    
+
     <Directory /var/www/MyApp/script>
         Options +ExecCGI
     </Directory>
-    
+
     <Location />
         SetHandler  perl-script
         PerlHandler Apache::Registry
     </Location>
-    
+
 script/myapp_registry.pl (you will need to create this):
 
     #!/usr/bin/perl
-    
+
     use strict;
     use warnings;
     use MyApp;
-    
+
     MyApp->handle_request( Apache->request );
-    
+
 =head1 METHODS
 
 =head2 ok_constant
@@ -114,17 +110,4 @@
 
 L<Catalyst>, L<Catalyst::Engine>, L<Catalyst::Engine::Apache>.
 
-=head1 AUTHORS
-
-Sebastian Riedel, <sri at cpan.org>
-
-Christian Hansen, <ch at ngmedia.com>
-
-Andy Grundman, <andy at hybridized.org>
-
-=head1 COPYRIGHT
-
-This program is free software, you can redistribute it and/or modify it under
-the same terms as Perl itself.
-
 =cut

Modified: Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache.pm
===================================================================
--- Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache.pm	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache.pm	2010-10-04 22:34:18 UTC (rev 13640)
@@ -1,4 +1,5 @@
 package Catalyst::Engine::Apache;
+# ABSTRACT: Catalyst Apache Engines
 
 use strict;
 use warnings;
@@ -9,13 +10,11 @@
 use URI::http;
 use URI::https;
 
-use constant MP2 => ( 
-    exists $ENV{MOD_PERL_API_VERSION} and 
+use constant MP2 => (
+    exists $ENV{MOD_PERL_API_VERSION} and
            $ENV{MOD_PERL_API_VERSION} >= 2
 );
 
-our $VERSION = '1.15';
-
 __PACKAGE__->mk_accessors(qw/apache return/);
 
 sub prepare_request {
@@ -35,7 +34,7 @@
         unless ( $c->config->{using_frontend_proxy} ) {
             last PROXY_CHECK if $c->request->address ne '127.0.0.1';
             last PROXY_CHECK if $c->config->{ignore_frontend_proxy};
-        }        
+        }
         last PROXY_CHECK unless $headers->{'X-Forwarded-For'};
 
         # If we are running as a backend server, the user will always appear
@@ -53,7 +52,7 @@
     if ($INC{'Apache2/ModSSL.pm'}) {
         $c->request->secure(1) if $self->apache->connection->is_https;
     } else {
-        my $https = $self->apache->subprocess_env('HTTPS'); 
+        my $https = $self->apache->subprocess_env('HTTPS');
         $c->request->secure(1) if defined $https and uc $https eq 'ON';
     }
 
@@ -61,7 +60,7 @@
 
 sub prepare_query_parameters {
     my ( $self, $c ) = @_;
-    
+
     if ( my $query_string = $self->apache->args ) {
         $self->SUPER::prepare_query_parameters( $c, $query_string );
     }
@@ -92,7 +91,7 @@
             last PROXY_CHECK if $c->config->{ignore_frontend_proxy};
         }
         last PROXY_CHECK unless $c->request->header( 'X-Forwarded-Host' );
-        
+
         $host = $c->request->header( 'X-Forwarded-Host' );
 
         if ( $host =~ /^(.+):(\d+)$/ ) {
@@ -112,19 +111,19 @@
     if ( $location && $location ne '/' ) {
         $base_path = $location;
     }
-    
+
     # Using URI directly is way too slow, so we construct the URLs manually
     my $uri_class = "URI::$scheme";
-    
+
     if ( $port !~ /^(?:80|443)$/ && $host !~ /:/ ) {
         $host .= ":$port";
     }
-    
+
     # We want the path before Apache escapes it.  Under mod_perl2 this is available
     # with the unparsed_uri method.  Under mod_perl 1 we must parse it out of the
     # request line.
     my ($path, $qs);
-    
+
     if ( MP2 ) {
         ($path, $qs) = split /\?/, $self->apache->unparsed_uri, 2;
     }
@@ -132,13 +131,13 @@
         my (undef, $path_query) = split / /, $self->apache->the_request, 3;
         ($path, $qs)            = split /\?/, $path_query, 2;
     }
-    
+
     # Don't check for LocationMatch blocks if requested
     # http://rt.cpan.org/Ticket/Display.html?id=26921
     if ( $self->apache->dir_config('CatalystDisableLocationMatch') ) {
         $base_path = '';
     }
-        
+
     # Check if $base_path appears to be a regex (contains invalid characters),
     # meaning we're in a LocationMatch block
     elsif ( $base_path =~ m/[^$URI::uric]/o ) {
@@ -146,13 +145,13 @@
         # that will become our base
         my $match = qr/($base_path)/;
         my ($base_match) = $path =~ $match;
-        
+
         $base_path = $base_match || '';
     }
 
     # Strip leading slash
     $path =~ s{^/+}{};
-    
+
     # base must end in a slash
     $base_path .= '/' unless $base_path =~ m{/$};
 
@@ -162,7 +161,7 @@
     if ( defined $ENV{SCRIPT_NAME} && $self->apache->filename && -f $self->apache->filename && -x _ ) {
         $base_path .= $ENV{SCRIPT_NAME};
     }
-    
+
     # If the path is contained within the base, we need to make the path
     # match base.  This handles the case where the app is running at /deep/path
     # but a request to /deep/path fails where /deep/path/ does not.
@@ -170,12 +169,12 @@
         $path = $base_path;
         $path =~ s{^/+}{};
     }
-    
+
     my $query = $qs ? '?' . $qs : '';
     my $uri   = $scheme . '://' . $host . '/' . $path . $query;
 
     $c->request->uri( bless \$uri, $uri_class );
-    
+
     my $base_uri = $scheme . '://' . $host . $base_path;
 
     $c->request->base( bless \$base_uri, $uri_class );
@@ -184,15 +183,15 @@
 sub read_chunk {
     my $self = shift;
     my $c = shift;
-    
+
     $self->apache->read( @_ );
 }
 
 sub finalize_body {
     my ( $self, $c ) = @_;
-    
+
     $self->SUPER::finalize_body($c);
-    
+
     # Data sent using $self->apache->print is buffered, so we need
     # to flush it after we are done writing.
     $self->apache->rflush;
@@ -245,12 +244,7 @@
 }
 
 1;
-__END__
 
-=head1 NAME
-
-Catalyst::Engine::Apache - Catalyst Apache Engines
-
 =head1 SYNOPSIS
 
 For example Apache configurations, see the documentation for the engine that
@@ -276,7 +270,7 @@
 
 =head2 $c->engine->return
 
-If you need to return something other than OK from the mod_perl handler, 
+If you need to return something other than OK from the mod_perl handler,
 you may set any other Apache constant in this method.  You should only use
 this method if you know what you are doing or bad things may happen!
 For example, to return DECLINED in mod_perl 2:
@@ -340,25 +334,4 @@
 
 L<Catalyst> L<Catalyst::Engine>.
 
-=head1 MAINTAINERS
-
-Current maintainer, Tomas Doran (t0m) C<< <bobtfish at bobtfish.net> >>.
-
-=head1 AUTHORS
-
-Sebastian Riedel, C<< <sri at cpan.org> >>.
-
-Christian Hansen, C<< <ch at ngmedia.com> >>.
-
-Andy Grundman, C<< <andy at hybridized.org> >>.
-
-=head1 COPYRIGHT
-
-Copyright 2005-2010 by the above above listed "AUTHORS" and "MAINTAINERS".
-
-=head1 LICENSE
-
-This program is free software, you can redistribute it and/or modify it under
-the same terms as Perl itself.
-
 =cut

Modified: Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2/MP19.pm
===================================================================
--- Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2/MP19.pm	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2/MP19.pm	2010-10-04 22:34:18 UTC (rev 13640)
@@ -1,4 +1,5 @@
 package Catalyst::Engine::Apache2::MP19;
+# ABSTRACT: Catalyst Apache2 mod_perl 1.99x Engine
 
 use strict;
 use warnings;
@@ -18,50 +19,45 @@
 
 sub unescape_uri {
     my ( $self, $str ) = @_;
-    
+
     $str =~ s/\+/ /g;
     return Apache::URI::unescape_url($str);
 }
 
 1;
-__END__
 
-=head1 NAME
-
-Catalyst::Engine::Apache2::MP19 - Catalyst Apache2 mod_perl 1.99x Engine
-
 =head1 SYNOPSIS
 
     # Set up your Catalyst app as a mod_perl 1.99x application in httpd.conf
     PerlSwitches -I/var/www/MyApp/lib
-    
+
     # Preload your entire application
     PerlModule MyApp
-    
+
     <VirtualHost *>
         ServerName    myapp.hostname.com
         DocumentRoot  /var/www/MyApp/root
-        
+
         <Location />
             SetHandler          modperl
             PerlResponseHandler MyApp
         </Location>
-        
+
         # you can also run your app in any non-root location
         <Location /some/other/path>
             SetHandler          perl-script
             PerlResponseHandler MyApp
         </Location>
-        
+
         # Make sure to let Apache handle your static files
-        # (It is not necessary to remove the Static::Simple plugin 
+        # (It is not necessary to remove the Static::Simple plugin
         # in production; Apache will bypass Static::Simple if
         # configured in this way)
 
         <Location /static>
             SetHandler          default-handler
         </Location>
- 
+
         # If not running at a root location in a VirtualHost,
         # you'll probably need to set an Alias to the location
         # of your static files, and allow access to this location:
@@ -99,26 +95,26 @@
 
     PerlModule ModPerl::Registry
     Alias / /var/www/MyApp/script/myapp_registry.pl/
-    
+
     <Directory /var/www/MyApp/script>
         Options +ExecCGI
     </Directory>
-    
+
     <Location />
         SetHandler          perl-script
         PerlResponseHandler ModPerl::Registry
     </Location>
-    
+
 script/myapp_registry.pl (you will need to create this):
 
     #!/usr/bin/perl
-    
+
     use strict;
     use warnings;
     use MyApp;
-    
+
     MyApp->handle_request( Apache::RequestUtil->request );
-    
+
 =head1 METHODS
 
 =head2 ok_constant
@@ -127,17 +123,4 @@
 
 L<Catalyst>, L<Catalyst::Engine>, L<Catalyst::Engine::Apache2>.
 
-=head1 AUTHORS
-
-Sebastian Riedel, <sri at cpan.org>
-
-Christian Hansen, <ch at ngmedia.com>
-
-Andy Grundman, <andy at hybridized.org>
-
-=head1 COPYRIGHT
-
-This program is free software, you can redistribute it and/or modify it under
-the same terms as Perl itself.
-
 =cut

Modified: Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2/MP20.pm
===================================================================
--- Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2/MP20.pm	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2/MP20.pm	2010-10-04 22:34:18 UTC (rev 13640)
@@ -1,4 +1,5 @@
 package Catalyst::Engine::Apache2::MP20;
+# ABSTRACT: Catalyst Apache2 mod_perl 2.x Engine
 
 use strict;
 use warnings;
@@ -20,50 +21,45 @@
 
 sub unescape_uri {
     my ( $self, $str ) = @_;
-    
+
     $str =~ s/\+/ /g;
     return Apache2::URI::unescape_url($str);
 }
 
 1;
-__END__
 
-=head1 NAME
-
-Catalyst::Engine::Apache2::MP20 - Catalyst Apache2 mod_perl 2.x Engine
-
 =head1 SYNOPSIS
 
     # Set up your Catalyst app as a mod_perl 2.x application in httpd.conf
     PerlSwitches -I/var/www/MyApp/lib
-    
+
     # Preload your entire application
     PerlModule MyApp
-    
+
     <VirtualHost *>
         ServerName    myapp.hostname.com
         DocumentRoot  /var/www/MyApp/root
-        
+
         <Location />
             SetHandler          modperl
             PerlResponseHandler MyApp
         </Location>
-        
+
         # you can also run your app in any non-root location
         <Location /some/other/path>
             SetHandler          perl-script
             PerlResponseHandler MyApp
         </Location>
-        
+
         # Make sure to let Apache handle your static files
-        # (It is not necessary to remove the Static::Simple plugin 
+        # (It is not necessary to remove the Static::Simple plugin
         # in production; Apache will bypass Static::Simple if
         # configured in this way)
 
         <Location /static>
             SetHandler          default-handler
         </Location>
- 
+
         # If not running at a root location in a VirtualHost,
         # you'll probably need to set an Alias to the location
         # of your static files, and allow access to this location:
@@ -91,24 +87,24 @@
 
     PerlModule ModPerl::Registry
     Alias / /var/www/MyApp/script/myapp_registry.pl/
-    
+
     <Directory /var/www/MyApp/script>
         Options +ExecCGI
     </Directory>
-    
+
     <Location />
         SetHandler          perl-script
         PerlResponseHandler ModPerl::Registry
     </Location>
-    
+
 script/myapp_registry.pl (you will need to create this):
 
     #!/usr/bin/perl
-    
+
     use strict;
     use warnings;
     use MyApp;
-    
+
     MyApp->handle_request( Apache2::RequestUtil->request );
 
 =head1 METHODS
@@ -121,7 +117,7 @@
 
 =over 4
 
-=item unescape_uri 
+=item unescape_uri
 
 =back
 
@@ -131,7 +127,7 @@
 
 =over 4
 
-=item unescape_uri 
+=item unescape_uri
 
 =back
 
@@ -139,17 +135,4 @@
 
 L<Catalyst>, L<Catalyst::Engine>, L<Catalyst::Engine::Apache2>.
 
-=head1 AUTHORS
-
-Sebastian Riedel, <sri at cpan.org>
-
-Christian Hansen, <ch at ngmedia.com>
-
-Andy Grundman, <andy at hybridized.org>
-
-=head1 COPYRIGHT
-
-This program is free software, you can redistribute it and/or modify it under
-the same terms as Perl itself.
-
 =cut

Modified: Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2.pm
===================================================================
--- Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2.pm	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/lib/Catalyst/Engine/Apache2.pm	2010-10-04 22:34:18 UTC (rev 13640)
@@ -1,4 +1,5 @@
 package Catalyst::Engine::Apache2;
+# ABSTRACT: Base class for Apache 1.99x and 2.x Engines
 
 use strict;
 use warnings;
@@ -20,12 +21,7 @@
 }
 
 1;
-__END__
 
-=head1 NAME
-
-Catalyst::Engine::Apache2 - Base class for Apache 1.99x and 2.x Engines
-
 =head1 SYNOPSIS
 
 See L<Catalyst>.
@@ -48,17 +44,4 @@
 
 L<Catalyst> L<Catalyst::Engine>.
 
-=head1 AUTHORS
-
-Sebastian Riedel, <sri at cpan.org>
-
-Christian Hansen, <ch at ngmedia.com>
-
-Andy Grundman, <andy at hybridized.org>
-
-=head1 COPYRIGHT
-
-This program is free software, you can redistribute it and/or modify it under
-the same terms as Perl itself.
-
 =cut

Modified: Catalyst-Engine-Apache/trunk/t/00compiles.t
===================================================================
--- Catalyst-Engine-Apache/trunk/t/00compiles.t	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/t/00compiles.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 
-use Test::More;
+use Test::More 0.88;
 
 use_ok 'Catalyst::Engine::Apache';
 

Modified: Catalyst-Engine-Apache/trunk/t/lib/ACLTestApp.pm
===================================================================
--- Catalyst-Engine-Apache/trunk/t/lib/ACLTestApp.pm	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/t/lib/ACLTestApp.pm	2010-10-04 22:34:18 UTC (rev 13640)
@@ -14,8 +14,8 @@
     my ( $class, $action ) = @_;
 
     if ( Scalar::Util::blessed($action)
-	 and $action->name ne "foobar" ) {
-	eval { $c->detach( 'foobar', [$action, 'foo'] ) };
+     and $action->name ne "foobar" ) {
+    eval { $c->detach( 'foobar', [$action, 'foo'] ) };
     }
 
     $c->next::method( @_ );

Modified: Catalyst-Engine-Apache/trunk/t/lib/TestApp/Controller/Action/Chained.pm
===================================================================
--- Catalyst-Engine-Apache/trunk/t/lib/TestApp/Controller/Action/Chained.pm	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/t/lib/TestApp/Controller/Action/Chained.pm	2010-10-04 22:34:18 UTC (rev 13640)
@@ -165,21 +165,21 @@
 sub mult_nopp_idnew : Chained('mult_nopp_id') PathPart('new') Args(0) { }
 
 #
-#	Test Choice between branches and early return logic
+#   Test Choice between branches and early return logic
 #   Declaration order is important for $children->{$*}, since this is first match best.
 #
-sub cc_base 	: Chained('/') 		 PathPart('chained/choose_capture') CaptureArgs(0) { }
-sub cc_link  	: Chained('cc_base') PathPart('') 						CaptureArgs(0) { }
-sub cc_anchor 	: Chained('cc_link') PathPart('anchor.html') 			Args(0) 	   { }
-sub cc_all     	: Chained('cc_base') PathPart('') 						Args() 		   { }
+sub cc_base     : Chained('/')       PathPart('chained/choose_capture') CaptureArgs(0) { }
+sub cc_link     : Chained('cc_base') PathPart('')                       CaptureArgs(0) { }
+sub cc_anchor   : Chained('cc_link') PathPart('anchor.html')            Args(0)        { }
+sub cc_all      : Chained('cc_base') PathPart('')                       Args()         { }
 
-sub cc_a		: Chained('cc_base') 	PathPart('') 	CaptureArgs(1) { }
-sub cc_a_link	: Chained('cc_a') 	 	PathPart('a') 	CaptureArgs(0) { }
-sub cc_a_anchor	: Chained('cc_a_link')  PathPart('') 	Args() 		   { }
+sub cc_a        : Chained('cc_base')    PathPart('')    CaptureArgs(1) { }
+sub cc_a_link   : Chained('cc_a')       PathPart('a')   CaptureArgs(0) { }
+sub cc_a_anchor : Chained('cc_a_link')  PathPart('')    Args()         { }
 
-sub cc_b		: Chained('cc_base') 	PathPart('b') 				CaptureArgs(0) { }
-sub cc_b_link	: Chained('cc_b') 	 	PathPart('') 				CaptureArgs(1) { }
-sub cc_b_anchor	: Chained('cc_b_link')  PathPart('anchor.html') 	Args() 		   { }
+sub cc_b        : Chained('cc_base')    PathPart('b')               CaptureArgs(0) { }
+sub cc_b_link   : Chained('cc_b')       PathPart('')                CaptureArgs(1) { }
+sub cc_b_anchor : Chained('cc_b_link')  PathPart('anchor.html')     Args()         { }
 
 #
 #   Test static paths vs. captures

Modified: Catalyst-Engine-Apache/trunk/t/lib/TestApp/Controller/Action/Streaming.pm
===================================================================
--- Catalyst-Engine-Apache/trunk/t/lib/TestApp/Controller/Action/Streaming.pm	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/t/lib/TestApp/Controller/Action/Streaming.pm	2010-10-04 22:34:18 UTC (rev 13640)
@@ -17,7 +17,7 @@
 sub body : Local {
     my ( $self, $c ) = @_;
 
-    my $file = "$FindBin::Bin/../lib/TestApp/Controller/Action/Streaming.pm";
+    my $file = "$FindBin::Bin/lib/TestApp/Controller/Action/Streaming.pm";
     my $fh = IO::File->new( $file, 'r' );
     if ( defined $fh ) {
         $c->res->body( $fh );

Modified: Catalyst-Engine-Apache/trunk/t/optional/mod_perl-locationmatch.pl
===================================================================
--- Catalyst-Engine-Apache/trunk/t/optional/mod_perl-locationmatch.pl	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/t/optional/mod_perl-locationmatch.pl	2010-10-04 22:34:18 UTC (rev 13640)
@@ -4,7 +4,7 @@
 #
 # Note, to get this to run properly, you may need to give it the path to your
 # httpd.conf:
-# 
+#
 # perl t/optional/mod_perl-locationmatch.pl -httpd_conf /etc/apache/httpd.conf
 #
 # For debugging, you can start TestApp and leave it running with

Modified: Catalyst-Engine-Apache/trunk/t/optional/mod_perl-non-root.pl
===================================================================
--- Catalyst-Engine-Apache/trunk/t/optional/mod_perl-non-root.pl	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/t/optional/mod_perl-non-root.pl	2010-10-04 22:34:18 UTC (rev 13640)
@@ -4,7 +4,7 @@
 #
 # Note, to get this to run properly, you may need to give it the path to your
 # httpd.conf:
-# 
+#
 # perl t/optional/mod_perl-non-root.pl -httpd_conf /etc/apache/httpd.conf
 #
 # For debugging, you can start TestApp and leave it running with

Modified: Catalyst-Engine-Apache/trunk/t/optional/mod_perl.pl
===================================================================
--- Catalyst-Engine-Apache/trunk/t/optional/mod_perl.pl	2010-10-04 19:17:09 UTC (rev 13639)
+++ Catalyst-Engine-Apache/trunk/t/optional/mod_perl.pl	2010-10-04 22:34:18 UTC (rev 13640)
@@ -4,7 +4,7 @@
 #
 # Note, to get this to run properly, you may need to give it the path to your
 # httpd.conf:
-# 
+#
 # perl t/optional/mod_perl.pl -httpd_conf /etc/apache/httpd.conf
 #
 # For debugging, you can start TestApp and leave it running with

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_action.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_action.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_action.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_action.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,110 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 28 * $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'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action_action_four'),
+            '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_four', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Action',
+            'Test Class'
+        );
+        is( $response->header('X-TestAppActionTestMyAction'), 'MyAction works' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_auto.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_auto.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_auto.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_auto.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,136 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 18*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+
+    # new dispatcher:
+    # 11 wallclock secs (10.14 usr +  0.20 sys = 10.34 CPU) @ 15.18/s (n=157)
+    # old dispatcher (r1486):
+    # 11 wallclock secs (10.34 usr +  0.20 sys = 10.54 CPU) @ 13.76/s (n=145)
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    # test auto + local method
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto->one
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/auto/one'), 'auto + local' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'one', 'Content OK' );
+    }
+
+    # test auto + default
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto->default
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/auto/anything'), 'auto + default' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'default', 'Content OK' );
+    }
+
+    # test auto + auto + local
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto::Deep->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto::Deep->auto
+          TestApp::Controller::Action::Auto::Deep->one
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/auto/deep/one'), 'auto + auto + local' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'deep one', 'Content OK' );
+    }
+
+    # test auto + auto + default
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto::Deep->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto::Deep->auto
+          TestApp::Controller::Action::Auto::Deep->default
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/auto/deep/anything'), 'auto + auto + default' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'deep default', 'Content OK' );
+    }
+
+    # test auto + failing auto + local + end
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto::Abort->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto::Abort->auto
+          TestApp::Controller::Action::Auto::Abort->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/auto/abort/one'), 'auto + failing auto + local' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'abort end', 'Content OK' );
+    }
+
+    # test auto + default (bug on invocation of default twice)
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto::Default->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto::Default->auto
+          TestApp::Controller::Action::Auto::Default->default
+          TestApp::Controller::Action::Auto::Default->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/auto/default/moose'), 'auto + default' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'default (auto: 1)', 'Content OK' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_begin.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_begin.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_begin.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_begin.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,53 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 7*$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 {
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Begin->begin
+          TestApp::Controller::Action::Begin->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/begin'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Begin',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like( $response->content, qr/'Catalyst::Request'/,
+            'Content is a serialized Catalyst::Request' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_chained.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_chained.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_chained.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_chained.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,831 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 118*$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 {
+    my ($run_number) = @_;
+
+    #
+    #   This is a simple test where the parent and child actions are
+    #   within the same controller.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->foo
+          TestApp::Controller::Action::Chained->endpoint
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/foo/1/end/2'), 'chained + local endpoint' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   This makes sure the above isn't found if the argument for the
+    #   end action isn't supplied.
+    #
+    {
+        my $expected = undef;
+
+        ok( my $response = request('http://localhost/chained/foo/1/end'),
+            'chained + local endpoint; missing last argument' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->code, 500, 'Status OK' );
+    }
+
+    #
+    #   Tests the case when the child action is placed in a subcontroller.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->foo
+          TestApp::Controller::Action::Chained::Foo->spoon
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/foo/1/spoon'), 'chained + subcontroller endpoint' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; ', 'Content OK' );
+    }
+
+    #
+    #   Tests if the relative specification (e.g.: Chained('bar') ) works
+    #   as expected.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->bar
+          TestApp::Controller::Action::Chained->finale
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/bar/1/spoon'), 'chained + relative endpoint' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 1, spoon', 'Content OK' );
+    }
+
+    #
+    #   Just a test for multiple arguments.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->foo2
+          TestApp::Controller::Action::Chained->endpoint2
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/foo2/10/20/end2/15/25'),
+            'chained + local (2 args each)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '10, 20; 15, 25', 'Content OK' );
+    }
+
+    #
+    #   The first three-chain test tries to call the action with :Args(1)
+    #   specification. There's also a one action with a :CaptureArgs(1)
+    #   attribute, that should not be dispatched to.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->one_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/one/23'),
+            'three-chain (only first)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 23', 'Content OK' );
+    }
+
+    #
+    #   This is the second three-chain test, it goes for the action that
+    #   handles "/one/$cap/two/$arg1/$arg2" paths. Should be the two action
+    #   having :Args(2), not the one having :CaptureArgs(2).
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->one
+          TestApp::Controller::Action::Chained->two_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/one/23/two/23/46'),
+            'three-chain (up to second)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '23; 23, 46', 'Content OK' );
+    }
+
+    #
+    #   Last of the three-chain tests. Has no concurrent action with :CaptureArgs
+    #   and is more thought to simply test the chain as a whole and the 'two'
+    #   action specifying :CaptureArgs.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->one
+          TestApp::Controller::Action::Chained->two
+          TestApp::Controller::Action::Chained->three_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/one/23/two/23/46/three/1/2/3'),
+            'three-chain (all three)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '23, 23, 46; 1, 2, 3', 'Content OK' );
+    }
+
+    #
+    #   Tests dispatching on number of arguments for :Args. This should be
+    #   dispatched to the action expecting one argument.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->multi1
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/multi/23'),
+            'multi-action (one arg)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 23', 'Content OK' );
+    }
+
+    #
+    #   Belongs to the former test and goes for the action expecting two arguments.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->multi2
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/multi/23/46'),
+            'multi-action (two args)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 23, 46', 'Content OK' );
+    }
+
+    #
+    #   Dispatching on argument count again, this time we provide too many
+    #   arguments, so dispatching should fail.
+    #
+    {
+        my $expected = undef;
+
+        ok( my $response = request('http://localhost/chained/multi/23/46/67'),
+            'multi-action (three args, should lead to error)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->code, 500, 'Status OK' );
+    }
+
+    #
+    #   This tests the case when an action says it's the child of an action in
+    #   a subcontroller.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Foo->higher_root
+          TestApp::Controller::Action::Chained->higher_root
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/higher_root/23/bar/11'),
+            'root higher than child' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '23; 11', 'Content OK' );
+    }
+
+    #
+    #   Just a more complex version of the former test. It tests if a controller ->
+    #   subcontroller -> controller dispatch works.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->pcp1
+          TestApp::Controller::Action::Chained::Foo->pcp2
+          TestApp::Controller::Action::Chained->pcp3
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/pcp1/1/pcp2/2/pcp3/3'),
+            'parent -> child -> parent' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1, 2; 3', 'Content OK' );
+    }
+
+    #
+    #   Tests dispatch on capture number. This test is for a one capture action.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->multi_cap1
+          TestApp::Controller::Action::Chained->multi_cap_end1
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/multi_cap/1/baz'),
+            'dispatch on capture num 1' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; ', 'Content OK' );
+    }
+
+    #
+    #   Belongs to the former test. This one goes for the action expecting two
+    #   captures.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->multi_cap2
+          TestApp::Controller::Action::Chained->multi_cap_end2
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/multi_cap/1/2/baz'),
+            'dispatch on capture num 2' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1, 2; ', 'Content OK' );
+    }
+
+    #
+    #   Tests the priority of a slurpy arguments action (with :Args) against
+    #   two actions chained together. The two actions should win.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->priority_a2
+          TestApp::Controller::Action::Chained->priority_a2_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/priority_a/1/end/2'),
+            'priority - slurpy args vs. parent/child' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   This belongs to the former test but tests if two chained actions have
+    #   priority over an action with the exact arguments.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->priority_b2
+          TestApp::Controller::Action::Chained->priority_b2_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/priority_b/1/end/2'),
+            'priority - fixed args vs. parent/child' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   This belongs to the former test but tests if two chained actions have
+    #   priority over an action with one child action not having the Args() attr set.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->priority_c1
+          TestApp::Controller::Action::Chained->priority_c2_xyz
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/priority_c/1/xyz/'),
+            'priority - no Args() order mismatch' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; ', 'Content OK' );
+    }
+
+    #
+    #   Test dispatching between two controllers that are on the same level and
+    #   therefor have no parent/child relationship.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Bar->cross1
+          TestApp::Controller::Action::Chained::Foo->cross2
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/cross/1/end/2'),
+            'cross controller w/o par/child relation' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   This is for testing if the arguments got passed to the actions
+    #   correctly.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::PassedArgs->first
+          TestApp::Controller::Action::Chained::PassedArgs->second
+          TestApp::Controller::Action::Chained::PassedArgs->third
+          TestApp::Controller::Action::Chained::PassedArgs->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/passedargs/a/1/b/2/c/3'),
+            'Correct arguments passed to actions' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2; 3', 'Content OK' );
+    }
+
+    #
+    #   The :Args attribute is optional, we check the action not specifying
+    #   it with these tests.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->opt_args
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/opt_args/1/2/3'),
+            'Optional :Args attribute working' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 1, 2, 3', 'Content OK' );
+    }
+
+    #
+    #   Tests for optional PathPart attribute.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->opt_pp_start
+          TestApp::Controller::Action::Chained->opt_pathpart
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/optpp/1/opt_pathpart/2'),
+            'Optional :PathName attribute working' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Tests for optional PathPart *and* Args attributes.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->opt_all_start
+          TestApp::Controller::Action::Chained->oa
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/optall/1/oa/2/3'),
+            'Optional :PathName *and* :Args attributes working' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2, 3', 'Content OK' );
+    }
+
+    #
+    #   Test if :Chained is the same as :Chained('/')
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->rootdef
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/rootdef/23'),
+            ":Chained is the same as :Chained('/')" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 23', 'Content OK' );
+    }
+
+    #
+    #   Test if :Chained('.') is working
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->parentchain
+          TestApp::Controller::Action::Chained::ParentChain->child
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/parentchain/1/child/2'),
+            ":Chained('.') chains to parent controller action" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test behaviour of auto actions returning '1' for the chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Foo->auto
+          TestApp::Controller::Action::Chained::Auto->foo
+          TestApp::Controller::Action::Chained::Auto::Foo->fooend
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/autochain1/1/fooend/2'),
+            "Behaviour when auto returns 1 correct" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test behaviour of auto actions returning '0' for the chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Bar->auto
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/autochain2/1/barend/2'),
+            "Behaviour when auto returns 0 correct" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test what auto actions are run when namespaces are changed
+    #   horizontally.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Foo->auto
+          TestApp::Controller::Action::Chained::Auto::Bar->crossloose
+          TestApp::Controller::Action::Chained::Auto::Foo->crossend
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/auto_cross/1/crossend/2'),
+            "Correct auto actions are run on cross controller dispatch" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test forwarding from auto action in chain dispatch.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Forward->auto
+          TestApp::Controller::Action::Chained::Auto->fw3
+          TestApp::Controller::Action::Chained::Auto->fw1
+          TestApp::Controller::Action::Chained::Auto::Forward->forwardend
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/auto_forward/1/forwardend/2'),
+            "Forwarding out of auto in chain" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Detaching out of the auto action of a chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Detach->auto
+          TestApp::Controller::Action::Chained::Auto->fw3
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/auto_detach/1/detachend/2'),
+            "Detaching out of auto in chain" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test forwarding from auto action in chain dispatch.
+    #
+    {
+        my $expected = undef;
+
+        ok( my $response = request('http://localhost/chained/loose/23'),
+            "Loose end is not callable" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->code, 500, 'Status OK' );
+    }
+
+    #
+    #   Test forwarding out of a chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->chain_fw_a
+          TestApp::Controller::Action::Chained->fw_dt_target
+          TestApp::Controller::Action::Chained->chain_fw_b
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/chain_fw/1/end/2'),
+            "Forwarding out a chain" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test detaching out of a chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->chain_dt_a
+          TestApp::Controller::Action::Chained->fw_dt_target
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/chain_dt/1/end/2'),
+            "Forwarding out a chain" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Tests that an uri_for to a chained root index action
+    #   returns the right value.
+    #
+    {
+        ok( my $response = request(
+            'http://localhost/action/chained/to_root' ),
+            'uri_for with chained root action as arg' );
+        like( $response->content,
+            qr(URI:https?://[^/]+/),
+            'Correct URI generated' );
+    }
+
+    #
+    #   Test interception of recursive chains. This test was added because at
+    #   one point during the :Chained development, Catalyst used to hang on
+    #   recursive chains.
+    #
+    {
+        eval { require 'TestAppChainedRecursive.pm' };
+        if ($run_number == 1) {
+            ok( ! $@, "Interception of recursive chains" );
+        }
+        else { pass( "Interception of recursive chains already tested" ) }
+    }
+
+    #
+    #   Test failure of absolute path part arguments.
+    #
+    {
+        eval { require 'TestAppChainedAbsolutePathPart.pm' };
+        if ($run_number == 1) {
+            like( $@, qr(foo/foo),
+                "Usage of absolute path part argument emits error" );
+        }
+        else { pass( "Error on absolute path part arguments already tested" ) }
+    }
+
+    #
+    #   Test chained actions in the root controller
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained::Root->rootsub
+          TestApp::Controller::Action::Chained::Root->endpointsub
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/rootsub/1/endpointsub/2'), 'chained in root namespace' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '', 'Content OK' );
+    }
+
+    #
+    #   Complex path with multiple empty pathparts
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->mult_nopp_base
+          TestApp::Controller::Action::Chained->mult_nopp_all
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/mult_nopp'),
+            "Complex path with multiple empty pathparts" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; ', 'Content OK' );
+    }
+
+    #
+    #    Higher Args() hiding more specific CaptureArgs chains sections
+    #
+    {
+        my @expected = qw[
+            TestApp::Controller::Action::Chained->begin
+            TestApp::Controller::Action::Chained->cc_base
+            TestApp::Controller::Action::Chained->cc_link
+            TestApp::Controller::Action::Chained->cc_anchor
+            TestApp::Controller::Action::Chained->end
+            ];
+
+        my $expected = join ', ', @expected;
+
+        ok( my $response = request('http://localhost/chained/choose_capture/anchor.html'),
+            'Choose between an early Args() and a later more ideal chain' );
+        is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions');
+        is( $response->content => '; ', 'Content OK' );
+    }
+
+    #
+    #    Less specific chain not being seen correctly due to earlier looser capture
+    #
+    {
+        my @expected = qw[
+            TestApp::Controller::Action::Chained->begin
+            TestApp::Controller::Action::Chained->cc_base
+            TestApp::Controller::Action::Chained->cc_b
+            TestApp::Controller::Action::Chained->cc_b_link
+            TestApp::Controller::Action::Chained->cc_b_anchor
+            TestApp::Controller::Action::Chained->end
+            ];
+
+        my $expected = join ', ', @expected;
+
+        ok( my $response = request('http://localhost/chained/choose_capture/b/a/anchor.html'),
+            'Choose between a more specific chain and an earlier looser one' );
+        is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions');
+        is( $response->content => 'a; ', 'Content OK' );
+    }
+
+    #
+    #    Check we get the looser one when it's the correct match
+    #
+    {
+        my @expected = qw[
+            TestApp::Controller::Action::Chained->begin
+            TestApp::Controller::Action::Chained->cc_base
+            TestApp::Controller::Action::Chained->cc_a
+            TestApp::Controller::Action::Chained->cc_a_link
+            TestApp::Controller::Action::Chained->cc_a_anchor
+            TestApp::Controller::Action::Chained->end
+            ];
+
+        my $expected = join ', ', @expected;
+
+        ok( my $response = request('http://localhost/chained/choose_capture/a/a/anchor.html'),
+            'Choose between a more specific chain and an earlier looser one' );
+        is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions');
+        is( $response->content => 'a; anchor.html', 'Content OK' );
+    }
+
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_default.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_default.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_default.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_default.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,96 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 16 * $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 {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Default->begin
+          TestApp::Controller::Action::Default->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/default'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Default',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+
+        ok( $response = request('http://localhost/foo/bar/action'), 'Request' );
+        is( $response->code, 500, 'Invalid URI returned 500' );
+    }
+
+    # test that args are passed properly to default
+    {
+        my $creq;
+        my $expected = [qw/action default arg1 arg2/];
+
+        ok( my $response = request('http://localhost/action/default/arg1/arg2'),
+            'Request' );
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+        is_deeply( $creq->{arguments}, $expected, 'Arguments ok' );
+    }
+
+
+    # Test that /foo and /foo/ both do the same thing
+    {
+        my @expected = qw[
+          TestApp::Controller::Action->begin
+          TestApp::Controller::Action->default
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action'), 'Request' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected,
+            'Executed actions for /action'
+        );
+
+        ok( $response = request('http://localhost/action/'), 'Request' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected,
+            'Executed actions for /action/'
+        );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_detach.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_detach.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_detach.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_detach.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,100 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 18*$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 {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Detach->begin
+          TestApp::Controller::Action::Detach->one
+          TestApp::Controller::Action::Detach->two
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test detach to chain of actions.
+        ok( my $response = request('http://localhost/action/detach/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/detach/one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Detach',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+    }
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Detach->begin
+          TestApp::Controller::Action::Detach->path
+          TestApp::Controller::Action::Detach->two
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test detach to chain of actions.
+        ok( my $response = request('http://localhost/action/detach/path'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/detach/path', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Detach',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/detach/with_args/old'),
+            'Request with args'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'new' );
+    }
+
+    {
+        ok(
+            my $response = request(
+                'http://localhost/action/detach/with_method_and_args/old'),
+            'Request with args and method'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'new' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_end.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_end.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_end.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_end.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,54 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 7*$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 {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::End->begin
+          TestApp::Controller::Action::End->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::End->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/end'), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::End',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_forward.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_forward.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_forward.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_forward.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,238 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 47 * $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 {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Forward->begin
+          TestApp::Controller::Action::Forward->one
+          TestApp::Controller::Action::Forward->two
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test forward to global private action
+        ok( my $response = request('http://localhost/action/forward/global'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/forward/global', 'Main Class Action' );
+
+        # Test forward to chain of actions.
+        ok( $response = request('http://localhost/action/forward/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/forward/one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Forward',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Forward->begin
+          TestApp::Controller::Action::Forward->jojo
+          TestApp::Controller::Action::Forward->one
+          TestApp::Controller::Action::Forward->two
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/forward/jojo'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/forward/jojo', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Forward',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/forward/with_args/old'),
+            'Request with args'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'old' );
+    }
+
+    {
+        ok(
+            my $response = request(
+                'http://localhost/action/forward/with_method_and_args/old'),
+            'Request with args and method'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'old' );
+    }
+
+    # test forward with embedded args
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/forward/args_embed_relative'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'ok' );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/forward/args_embed_absolute'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'ok' );
+    }
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::TestRelative->begin
+          TestApp::Controller::Action::TestRelative->relative
+          TestApp::Controller::Action::Forward->one
+          TestApp::Controller::Action::Forward->two
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test forward to chain of actions.
+        ok( my $response = request('http://localhost/action/relative/relative'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/relative/relative', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::TestRelative',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::TestRelative->begin
+          TestApp::Controller::Action::TestRelative->relative_two
+          TestApp::Controller::Action::Forward->one
+          TestApp::Controller::Action::Forward->two
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test forward to chain of actions.
+        ok(
+            my $response =
+              request('http://localhost/action/relative/relative_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/relative/relative_two',
+            'Test Action'
+        );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::TestRelative',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    # test class forwards
+    {
+        ok(
+            my $response = request(
+                'http://localhost/action/forward/class_forward_test_action'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->header('X-Class-Forward-Test-Method'), 1,
+            'Test Method' );
+    }
+
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_global.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_global.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_global.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_global.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,83 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 18*$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_global_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_global_one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Global',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action_global_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_global_two', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Global',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action_global_three'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_global_three', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Global',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_index.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_index.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_index.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_index.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,100 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 20*$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 {
+    # test root index
+    {
+        my @expected = qw[
+          TestApp::Controller::Root->index
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+        ok( my $response = request('http://localhost/'), 'root index' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'root index', 'root index ok' );
+
+        ok( $response = request('http://localhost'), 'root index no slash' );
+        is( $response->content, 'root index', 'root index no slash ok' );
+    }
+
+    # test first-level controller index
+    {
+        my @expected = qw[
+          TestApp::Controller::Index->index
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/index/'), 'first-level controller index' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'Index index', 'first-level controller index ok' );
+
+        ok( $response = request('http://localhost/index'), 'first-level controller index no slash' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'Index index', 'first-level controller index no slash ok' );
+    }
+
+    # test second-level controller index
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Index->begin
+          TestApp::Controller::Action::Index->index
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/index/'), 'second-level controller index' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'Action-Index index', 'second-level controller index ok' );
+
+        ok( $response = request('http://localhost/action/index'), 'second-level controller index no slash' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'Action-Index index', 'second-level controller index no slash ok' );
+    }
+
+    # test controller default when index is present
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Index->begin
+          TestApp::Controller::Action::Index->default
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/index/foo'), 'default with index' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, "Error - TestApp::Controller::Action\n", 'default with index ok' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_inheritance.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_inheritance.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_inheritance.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_inheritance.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,119 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+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 {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Inheritance->begin
+          TestApp::Controller::Action::Inheritance->auto
+          TestApp::Controller::Action::Inheritance->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::Inheritance->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/inheritance'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Inheritance',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Inheritance::A->begin
+          TestApp::Controller::Action::Inheritance->auto
+          TestApp::Controller::Action::Inheritance::A->auto
+          TestApp::Controller::Action::Inheritance::A->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::Inheritance::A->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/inheritance/a'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Inheritance::A',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Inheritance::A::B->begin
+          TestApp::Controller::Action::Inheritance->auto
+          TestApp::Controller::Action::Inheritance::A->auto
+          TestApp::Controller::Action::Inheritance::A::B->auto
+          TestApp::Controller::Action::Inheritance::A::B->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::Inheritance::A::B->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/inheritance/a/b'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Inheritance::A::B',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_local.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_local.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_local.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_local.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,138 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 32*$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/local/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/local/one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/local/two/1/2'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/local/two', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+         ok( my $response = request('http://localhost/action/local/two'),
+               'Request' );
+         ok( !$response->is_success, 'Request with wrong number of args failed' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/local/three'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/local/three', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/local/four/five/six'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/local/four/five/six', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} ) {
+            skip "tests for %2F on remote server", 6;
+        }
+
+        ok(
+            my $response =
+              request('http://localhost/action/local/one/foo%2Fbar'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/local/one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr~arguments => \[\s*'foo/bar'\s*\]~,
+            "Parameters don't split on %2F"
+        );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_multipath.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_multipath.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_multipath.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_multipath.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,71 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+my $content = q/foo
+bar
+baz
+/;
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 16*$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 {
+    # Local
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/multipath/multipath'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $content, 'Content is a stream' );
+    }
+
+    # Global
+    {
+        ok( my $response = request('http://localhost/multipath'), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $content, 'Content is a stream' );
+    }
+
+    # Path('/multipath1')
+    {
+        ok( my $response = request('http://localhost/multipath1'), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $content, 'Content is a stream' );
+    }
+
+    # Path('multipath2')
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/multipath/multipath2'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $content, 'Content is a stream' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_path.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_path.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_path.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_path.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,127 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 30*$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/path/a%20path%20with%20spaces'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Catalyst-Action'),
+            'action/path/a%20path%20with%20spaces',
+            'Test Action'
+        );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/path/åäö'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/path/%C3%A5%C3%A4%C3%B6', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/path/'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/path', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/path/spaces_near_parens_singleq'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/path/spaces_near_parens_singleq', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/path/spaces_near_parens_doubleq'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/path/spaces_near_parens_doubleq', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_private.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_private.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_private.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_private.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,89 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 24*$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/private/one'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Private',
+            'Test Class'
+        );
+        is( $response->content, 'access denied', 'Access' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/private/two'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Private',
+            'Test Class'
+        );
+        is( $response->content, 'access denied', 'Access' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/three'), 'Request' );
+        ok( $response->is_error, 'Response Server Error 5xx' );
+        is( $response->content_type, 'text/html', 'Response Content-Type' );
+        like(
+            $response->header('X-Catalyst-Error'),
+            qr/^Unknown resource "three"/,
+            'Catalyst Error'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/private/four'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Private',
+            'Test Class'
+        );
+        is( $response->content, 'access denied', 'Access' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/private/five'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Private',
+            'Test Class'
+        );
+        is( $response->content, 'access denied', 'Access' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_regexp.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_regexp.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_regexp.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_regexp.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,106 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 28*$iters;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+
+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/regexp/10/hello'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            '^action/regexp/(\d+)/(\w+)$', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Regexp',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/regexp/hello/10'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            '^action/regexp/(\w+)/(\d+)$', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Regexp',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/regexp/mandatory'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            '^action/regexp/(mandatory)(/optional)?$', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Regexp',
+            'Test Class'
+        );
+        my $content = $response->content;
+        my $req = eval $content;
+
+        is( scalar @{ $req->captures }, 2, 'number of captures' );
+        is( $req->captures->[ 0 ], 'mandatory', 'mandatory capture' );
+        ok( !defined $req->captures->[ 1 ], 'optional capture' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/regexp/mandatory/optional'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            '^action/regexp/(mandatory)(/optional)?$', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Regexp',
+            'Test Class'
+        );
+        my $content = $response->content;
+        my $req = eval $content;
+
+        is( scalar @{ $req->captures }, 2, 'number of captures' );
+        is( $req->captures->[ 0 ], 'mandatory', 'mandatory capture' );
+        is( $req->captures->[ 1 ], '/optional', 'optional capture' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_streaming.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_action_streaming.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_streaming.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_action_streaming.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,72 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 10*$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 {
+    # test direct streaming
+    {
+        ok( my $response = request('http://localhost/streaming'), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+
+        SKIP:
+        {
+            if ( $ENV{CATALYST_SERVER} ) {
+                skip "Using remote server", 1;
+            }
+
+            # XXX: Length should be undef here, but HTTP::Request::AsCGI sets it
+            is( $response->content_length, 12, 'Response Content-Length' );
+        }
+
+        is( $response->content,, <<'EOF', 'Content is a stream' );
+foo
+bar
+baz
+EOF
+    }
+
+    # test streaming by passing a handle to $c->res->body
+  SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} ) {
+            skip "Using remote server", 5;
+        }
+
+        my $file = "$FindBin::Bin/lib/TestApp/Controller/Action/Streaming.pm";
+        my $fh = IO::File->new( $file, 'r' );
+        my $buffer;
+        if ( defined $fh ) {
+            $fh->read( $buffer, 1024 );
+            $fh->close;
+        }
+
+        ok( my $response = request('http://localhost/action/streaming/body'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content_length, -s $file, 'Response Content-Length' );
+        is( $response->content, $buffer, 'Content is read from filehandle' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_args.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_component_controller_args.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_args.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_component_controller_args.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,97 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use URI::Escape;
+
+our @paths;
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1;
+
+    # add special paths to test here
+    @paths = (
+        # all reserved in uri's
+        qw~ : / ? [ ] @ ! $ & ' ( ) * + ; = ~, ',' , '#',
+
+        # unreserved
+        'a'..'z','A'..'Z',0..9,qw( - . _ ~ ),
+        " ",
+
+        # just to test %2F/%
+        [ qw~ / / ~ ],
+
+        # testing %25/%25
+        [ qw~ % % ~ ],
+    );
+}
+
+use Test::More tests => 6*@paths * $iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+
+    # new dispatcher:
+    # 11 wallclock secs (10.14 usr +  0.20 sys = 10.34 CPU) @ 15.18/s (n=157)
+    # old dispatcher (r1486):
+    # 11 wallclock secs (10.34 usr +  0.20 sys = 10.54 CPU) @ 13.76/s (n=145)
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    run_test_for($_) for @paths;
+}
+
+sub run_test_for {
+    my $test = shift;
+
+    my $path;
+    if (ref $test) {
+        $path = join "/", map uri_escape($_), @$test;
+        $test = join '', @$test;
+    } else {
+        $path = uri_escape($test);
+    }
+
+    SKIP:
+    {
+        # Skip %2F, ., [, (, and ) tests on real webservers
+        # Both Apache and lighttpd don't seem to like these
+        if ( $ENV{CATALYST_SERVER} && $path =~ /(?:%2F|\.|%5B|\(|\))/ ) {
+            skip "Skipping $path tests on remote server", 6;
+        }
+
+        my $response;
+
+        ok( $response = request("http://localhost/args/args/$path"), "Requested args for path $path");
+
+        is( $response->content, $test, "$test as args" );
+
+        undef $response;
+
+        ok( $response = request("http://localhost/args/params/$path"), "Requested params for path $path");
+
+        is( $response->content, $test, "$test as params" );
+
+        undef $response;
+
+        if( $test =~ m{/} ) {
+            $test =~ s{/}{}g;
+            $path = uri_escape( $test );
+        }
+
+        ok( $response = request("http://localhost/chained/multi_cap/$path/baz"), "Requested capture for path $path");
+
+        is( $response->content, join( ', ', split( //, $test ) ) ."; ", "$test as capture" );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_body.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_request_body.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_body.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_body.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,77 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 18;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use HTTP::Headers;
+use HTTP::Request::Common;
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'text/plain',
+        'Content'      => 'Hello Catalyst'
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like( $response->content, qr/'Catalyst::Request'/,
+        'Content is a serialized Catalyst::Request' );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method,       'POST',       'Catalyst::Request method' );
+    is( $creq->content_type, 'text/plain', 'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+}
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'text/plain',
+        'Content'      => 'x' x 100_000
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method,       'POST',       'Catalyst::Request method' );
+    is( $creq->content_type, 'text/plain', 'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_body_demand.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_request_body_demand.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_body_demand.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_body_demand.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,66 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 8;
+use Catalyst::Test 'TestAppOnDemand';
+
+use Catalyst::Request;
+use HTTP::Headers;
+use HTTP::Request::Common;
+
+# Test a simple POST request to make sure body parsing
+# works in on-demand mode.
+SKIP:
+{
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip "Using remote server", 8;
+    }
+
+    {
+        my $params;
+
+        my $request = POST(
+            'http://localhost/body/params',
+            'Content-Type' => 'application/x-www-form-urlencoded',
+            'Content'      => 'foo=bar&baz=quux'
+        );
+
+        my $expected = { foo => 'bar', baz => 'quux' };
+
+        ok( my $response = request($request), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+
+        {
+            no strict 'refs';
+            ok(
+                eval '$params = ' . $response->content,
+                'Unserialize params'
+            );
+        }
+
+        is_deeply( $params, $expected, 'Catalyst::Request body parameters' );
+    }
+
+    # Test reading chunks of the request body using $c->read
+    {
+        my $creq;
+
+        my $request = POST(
+            'http://localhost/body/read',
+            'Content-Type' => 'text/plain',
+            'Content'      => 'x' x 105_000
+        );
+
+        my $expected = '10000|10000|10000|10000|10000|10000|10000|10000|10000|10000|5000';
+
+        ok( my $response = request($request), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $expected, 'Response Content' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_cookies.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_request_cookies.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_cookies.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_cookies.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,45 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 13;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use CGI::Simple::Cookie;
+use HTTP::Headers;
+use HTTP::Request::Common;
+use URI;
+
+{
+    my $creq;
+
+    my $request = GET( 'http://localhost/dump/request',
+        'Cookie' => 'Catalyst=Cool; Cool=Catalyst', );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like( $response->content, qr/'Catalyst::Request'/,
+        'Content is a serialized Catalyst::Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    isa_ok( $creq, 'Catalyst::Request' );
+    isa_ok( $creq->cookies->{Catalyst}, 'CGI::Simple::Cookie',
+            'Cookie Catalyst' );
+    is( $creq->cookies->{Catalyst}->name, 'Catalyst', 'Cookie Catalyst name' );
+    is( $creq->cookies->{Catalyst}->value, 'Cool', 'Cookie Catalyst value' );
+    isa_ok( $creq->cookies->{Cool}, 'CGI::Simple::Cookie', 'Cookie Cool' );
+    is( $creq->cookies->{Cool}->name,  'Cool',     'Cookie Cool name' );
+    is( $creq->cookies->{Cool}->value, 'Catalyst', 'Cookie Cool value' );
+
+    my $cookies = {
+        Catalyst => $creq->cookies->{Catalyst},
+        Cool     => $creq->cookies->{Cool}
+    };
+
+    is_deeply( $creq->cookies, $cookies, 'Cookies' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_headers.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_request_headers.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_headers.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_headers.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,71 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 17;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use HTTP::Headers;
+use HTTP::Request::Common;
+
+{
+    my $creq;
+
+    my $request = GET( 'http://localhost/dump/request',
+        'User-Agent'       => 'MyAgen/1.0',
+        'X-Whats-Cool'     => 'Catalyst',
+        'X-Multiple'       => [ 1 .. 5 ],
+        'X-Forwarded-Host' => 'frontend.server.com',
+        'X-Forwarded-For'  => '192.168.1.1, 1.2.3.4',
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like( $response->content, qr/^bless\( .* 'Catalyst::Request' \)$/s, 'Content is a serialized Catalyst::Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    isa_ok( $creq, 'Catalyst::Request' );
+    isa_ok( $creq->headers, 'HTTP::Headers', 'Catalyst::Request->headers' );
+    is( $creq->header('X-Whats-Cool'), $request->header('X-Whats-Cool'), 'Catalyst::Request->header X-Whats-Cool' );
+
+    { # Test that multiple headers are joined as per RFC 2616 4.2 and RFC 3875 4.1.18
+
+        my $excpected = '1, 2, 3, 4, 5';
+        my $got       = $creq->header('X-Multiple'); # HTTP::Headers is context sensitive, "force" scalar context
+
+        is( $got, $excpected, 'Multiple message-headers are joined as a comma-separated list' );
+    }
+
+    is( $creq->header('User-Agent'), $request->header('User-Agent'), 'Catalyst::Request->header User-Agent' );
+
+    my $host = sprintf( '%s:%d', $request->uri->host, $request->uri->port );
+    is( $creq->header('Host'), $host, 'Catalyst::Request->header Host' );
+
+    SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} && $ENV{CATALYST_SERVER} !~ /127.0.0.1|localhost/ ) {
+            skip "Using remote server", 2;
+        }
+
+        is( $creq->base->host, 'frontend.server.com', 'Catalyst::Request proxied base' );
+        is( $creq->address, '1.2.3.4', 'Catalyst::Request proxied address' );
+    }
+
+    SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} ) {
+            skip "Using remote server", 4;
+        }
+        # test that we can ignore the proxy support
+        TestApp->config->{ignore_frontend_proxy} = 1;
+        ok( $response = request($request), 'Request' );
+        ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+        is( $creq->base, 'http://localhost/', 'Catalyst::Request non-proxied base' );
+        is( $creq->address, '127.0.0.1', 'Catalyst::Request non-proxied address' );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_parameters.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_request_parameters.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_parameters.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_parameters.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,129 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 35;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use HTTP::Headers;
+use HTTP::Request::Common;
+
+{
+    my $creq;
+
+    my $parameters = { 'a' => [qw(A b C d E f G)], };
+
+    my $query = join( '&', map { 'a=' . $_ } @{ $parameters->{a} } );
+
+    ok( my $response = request("http://localhost/dump/request?$query"),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'GET', 'Catalyst::Request method' );
+    is_deeply( $creq->{parameters}, $parameters,
+        'Catalyst::Request parameters' );
+}
+
+{
+    my $creq;
+    ok( my $response = request("http://localhost/dump/request?q=foo%2bbar"),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    ok( eval '$creq = ' . $response->content );
+    is $creq->{parameters}->{q}, 'foo+bar', '%2b not double decoded';
+}
+
+{
+    my $creq;
+
+    my $parameters = {
+        'a'     => [qw(A b C d E f G)],
+        '%'     => [ '%', '"', '& - &' ],
+        'blank' => '',
+    };
+
+    my $request = POST(
+        'http://localhost/dump/request/a/b?a=1&a=2&a=3',
+        'Content'      => $parameters,
+        'Content-Type' => 'application/x-www-form-urlencoded'
+    );
+
+    unshift( @{ $parameters->{a} }, 1, 2, 3 );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'POST', 'Catalyst::Request method' );
+    is_deeply( $creq->{parameters}, $parameters,
+        'Catalyst::Request parameters' );
+    is_deeply( $creq->arguments, [qw(a b)], 'Catalyst::Request arguments' );
+    is_deeply( $creq->{uploads}, {}, 'Catalyst::Request uploads' );
+    is_deeply( $creq->cookies,   {}, 'Catalyst::Request cookie' );
+}
+
+# http://dev.catalyst.perl.org/ticket/37
+# multipart/form-data parameters that contain 'http://'
+# was an HTTP::Message bug, but HTTP::Body handles it properly now
+{
+    my $creq;
+
+    my $parameters = {
+        'url'   => 'http://www.google.com',
+        'blank' => '',
+    };
+
+    my $request = POST( 'http://localhost/dump/request',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      => $parameters,
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is_deeply( $creq->{parameters}, $parameters, 'Catalyst::Request parameters' );
+}
+
+# raw query string support
+{
+    my $creq;
+
+    my $parameters = {
+        a     => 1,
+        blank => '',
+    };
+
+    my $request = POST(
+        'http://localhost/dump/request/a/b?query+string',
+        'Content'      => $parameters,
+        'Content-Type' => 'application/x-www-form-urlencoded'
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->{uri}->query, 'query+string', 'Catalyst::Request POST query_string' );
+    is( $creq->query_keywords, 'query string', 'Catalyst::Request query_keywords' );
+    is_deeply( $creq->{parameters}, $parameters, 'Catalyst::Request parameters' );
+
+    ok( $response = request('http://localhost/dump/request/a/b?x=1&y=1&z=1'), 'Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->{uri}->query, 'x=1&y=1&z=1', 'Catalyst::Request GET query_string' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_uploads.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_request_uploads.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_uploads.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_uploads.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,246 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use Catalyst::Request::Upload;
+use HTTP::Headers;
+use HTTP::Headers::Util 'split_header_words';
+use HTTP::Request::Common;
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'form-data',
+        'Content'      => [
+            'author-live_engine_request_cookies.t' =>
+              ["$FindBin::Bin/author-live_engine_request_cookies.t"],
+            'author-live_engine_request_headers.t' =>
+              ["$FindBin::Bin/author-live_engine_request_headers.t"],
+            'author-live_engine_request_uploads.t' =>
+              ["$FindBin::Bin/author-live_engine_request_uploads.t"],
+        ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'POST', 'Catalyst::Request method' );
+    is( $creq->content_type, 'multipart/form-data',
+        'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+
+    for my $part ( $request->parts ) {
+
+        my $disposition = $part->header('Content-Disposition');
+        my %parameters  = @{ ( split_header_words($disposition) )[0] };
+
+        my $upload = $creq->{uploads}->{ $parameters{filename} };
+
+        isa_ok( $upload, 'Catalyst::Request::Upload' );
+
+        is( $upload->type, $part->content_type, 'Upload Content-Type' );
+        is( $upload->size, length( $part->content ), 'Upload Content-Length' );
+
+        # make sure upload is accessible via legacy params->{$file}
+        is( $creq->{parameters}->{ $upload->filename },
+            $upload->filename, 'legacy param method ok' );
+
+        ok( !-e $upload->tempname, 'Upload temp file was deleted' );
+    }
+}
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      => [
+            'testfile' => ["$FindBin::Bin/author-live_engine_request_cookies.t"],
+            'testfile' => ["$FindBin::Bin/author-live_engine_request_headers.t"],
+            'testfile' => ["$FindBin::Bin/author-live_engine_request_uploads.t"],
+        ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'POST', 'Catalyst::Request method' );
+    is( $creq->content_type, 'multipart/form-data',
+        'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+
+    my @parts = $request->parts;
+
+    for ( my $i = 0 ; $i < @parts ; $i++ ) {
+
+        my $part        = $parts[$i];
+        my $disposition = $part->header('Content-Disposition');
+        my %parameters  = @{ ( split_header_words($disposition) )[0] };
+
+        my $upload = $creq->{uploads}->{ $parameters{name} }->[$i];
+
+        isa_ok( $upload, 'Catalyst::Request::Upload' );
+        is( $upload->type, $part->content_type, 'Upload Content-Type' );
+        is( $upload->filename, $parameters{filename}, 'Upload filename' );
+        is( $upload->size, length( $part->content ), 'Upload Content-Length' );
+
+        ok( !-e $upload->tempname, 'Upload temp file was deleted' );
+    }
+}
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/engine/request/uploads/slurp',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      =>
+          [ 'slurp' => ["$FindBin::Bin/author-live_engine_request_uploads.t"], ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->content, ( $request->parts )[0]->content, 'Content' );
+}
+
+{
+    my $request = POST(
+        'http://localhost/dump/request',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      =>
+          [ 'file' => ["$FindBin::Bin/catalyst_130pix.gif"], ]
+    );
+
+    # LWP will auto-correct Content-Length when using a remote server
+    SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} ) {
+            skip 'Using remote server', 2;
+        }
+
+        # Sending wrong Content-Length here and see if subequent requests fail
+        $request->header('Content-Length' => $request->header('Content-Length') + 1);
+
+        ok( my $response = request($request), 'Request' );
+        ok( !$response->is_success, 'Response Error' );
+    }
+
+    $request = POST(
+        'http://localhost/dump/request',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      =>
+          [ 'file1' => ["$FindBin::Bin/catalyst_130pix.gif"],
+            'file2' => ["$FindBin::Bin/catalyst_130pix.gif"], ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like( $response->content, qr/file1 => bless/, 'Upload with name file1');
+    like( $response->content, qr/file2 => bless/, 'Upload with name file2');
+}
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'form-data',
+        'Content'      => [
+            'testfile' => 'textfield value',
+            'testfile' => ["$FindBin::Bin/catalyst_130pix.gif"],
+        ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'POST', 'Catalyst::Request method' );
+    is( $creq->content_type, 'multipart/form-data',
+        'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+
+    my $param = $creq->{parameters}->{testfile};
+
+    ok( @$param == 2, '2 values' );
+    is( $param->[0], 'textfield value', 'correct value' );
+    like( $param->[1], qr/\Qcatalyst_130pix.gif/, 'filename' );
+
+    for my $part ( $request->parts ) {
+
+        my $disposition = $part->header('Content-Disposition');
+        my %parameters  = @{ ( split_header_words($disposition) )[0] };
+
+        next unless exists $parameters{filename};
+
+        my $upload = $creq->{uploads}->{ $parameters{name} };
+
+        isa_ok( $upload, 'Catalyst::Request::Upload' );
+
+        is( $upload->type, $part->content_type, 'Upload Content-Type' );
+        is( $upload->size, length( $part->content ), 'Upload Content-Length' );
+        is( $upload->filename, 'catalyst_130pix.gif' );
+    }
+}
+
+done_testing;

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_uri.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_request_uri.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_uri.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_request_uri.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,121 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 49;
+use Catalyst::Test 'TestApp';
+use Catalyst::Request;
+
+my $creq;
+
+# test that the path can be changed
+{
+    ok( my $response = request('http://localhost/engine/request/uri/change_path'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    like( $creq->uri, qr{/my/app/lives/here$}, 'URI contains new path' );
+}
+
+# test that path properly removes the base location
+{
+    ok( my $response = request('http://localhost/engine/request/uri/change_base'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    like( $creq->base, qr{/new/location}, 'Base URI contains new location' );
+    is( $creq->path, 'engine/request/uri/change_base', 'URI contains correct path' );
+}
+
+# test that base + path is correct
+{
+    ok( my $response = request('http://localhost/engine/request/uri'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->base . $creq->path, $creq->uri, 'Base + Path ok' );
+}
+
+# test base is correct for HTTPS URLs
+SKIP:
+{
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip 'Using remote server', 5;
+    }
+
+    local $ENV{HTTPS} = 'on';
+    ok( my $response = request('https://localhost/engine/request/uri'), 'HTTPS Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->base, 'https://localhost/', 'HTTPS base ok' );
+    is( $creq->uri, 'https://localhost/engine/request/uri', 'HTTPS uri ok' );
+}
+
+# test that we can use semi-colons as separators
+{
+    my $parameters = {
+        a => [ qw/1 2/ ],
+        b => 3,
+    };
+
+    ok( my $response = request('http://localhost/engine/request/uri?a=1;a=2;b=3'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->{uri}->query, 'a=1;a=2;b=3', 'Query string ok' );
+    is_deeply( $creq->{parameters}, $parameters, 'Parameters ok' );
+}
+
+# test that query params are unescaped properly
+{
+    ok( my $response = request('http://localhost/engine/request/uri?text=Catalyst%20Rocks'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->{uri}->query, 'text=Catalyst%20Rocks', 'Query string ok' );
+    is( $creq->{parameters}->{text}, 'Catalyst Rocks', 'Unescaped param ok' );
+}
+
+# test that uri_with adds params
+{
+    ok( my $response = request('http://localhost/engine/request/uri/uri_with'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( !defined $response->header( 'X-Catalyst-Param-a' ), 'param "a" ok' );
+    is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );
+}
+
+# test that uri_with adds params (and preserves)
+{
+    ok( my $response = request('http://localhost/engine/request/uri/uri_with?a=1'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->header( 'X-Catalyst-Param-a' ), '1', 'param "a" ok' );
+    is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );
+}
+
+# test that uri_with replaces params (and preserves)
+{
+    ok( my $response = request('http://localhost/engine/request/uri/uri_with?a=1&b=2'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->header( 'X-Catalyst-Param-a' ), '1', 'param "a" ok' );
+    is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );
+}
+
+# test that uri_with replaces params (and preserves)
+{
+    ok( my $response = request('http://localhost/engine/request/uri/uri_with_object'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    like( $response->header( 'X-Catalyst-Param-a' ), qr(https?://localhost[^/]*/), 'param "a" ok' );
+}
+
+# test that uri_with is utf8 safe
+{
+    ok( my $response = request("http://localhost/engine/request/uri/uri_with_utf8"), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    like( $response->header( 'X-Catalyst-uri-with' ), qr/%E2%98%A0$/, 'uri_with ok' );
+}
+
+# test with undef -- no warnings should be thrown
+{
+    ok( my $response = request("http://localhost/engine/request/uri/uri_with_undef"), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->header( 'X-Catalyst-warnings' ), 0, 'no warnings emitted' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_cookies.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_response_cookies.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_cookies.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_cookies.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,73 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 15;
+use Catalyst::Test 'TestApp';
+use HTTP::Headers::Util 'split_header_words';
+
+my $expected = {
+    catalyst => [qw|catalyst cool path /bah|],
+    cool     => [qw|cool catalyst path /|]
+};
+
+{
+    ok( my $response = request('http://localhost/engine/response/cookies/one'),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/cookies/one', 'Test Action' );
+
+    my $cookies = {};
+
+    for my $string ( $response->header('Set-Cookie') ) {
+        my $cookie = [ split_header_words $string];
+        $cookies->{ $cookie->[0]->[0] } = $cookie->[0];
+    }
+
+    is_deeply( $cookies, $expected, 'Response Cookies' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/cookies/two'),
+        'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 302, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/cookies/two', 'Test Action' );
+
+    my $cookies = {};
+
+    for my $string ( $response->header('Set-Cookie') ) {
+        my $cookie = [ split_header_words $string];
+        $cookies->{ $cookie->[0]->[0] } = $cookie->[0];
+    }
+
+    is_deeply( $cookies, $expected, 'Response Cookies' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/cookies/three'),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/cookies/three', 'Test Action' );
+
+    my $cookies = {};
+
+    for my $string ( $response->header('Set-Cookie') ) {
+        my $cookie = [ split_header_words $string];
+        $cookies->{ $cookie->[0]->[0] } = $cookie->[0];
+    }
+
+    is_deeply( $cookies, {
+        hash => [ qw(hash a&b&c path /) ],
+        this_is_the_real_name => [ qw(this_is_the_real_name foo&bar path /) ], # not "object"
+    }, 'Response Cookies' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_errors.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_response_errors.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_errors.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_errors.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,60 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 18;
+use Catalyst::Test 'TestApp';
+
+close STDERR;    # i'm naughty :)
+
+{
+    ok( my $response = request('http://localhost/engine/response/errors/one'),
+        'Request' );
+    ok( $response->is_error, 'Response Server Error 5xx' );
+    is( $response->code,         500,         'Response Code' );
+    is( $response->content_type, 'text/html', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/errors/one', 'Test Action' );
+    like(
+        $response->header('X-Catalyst-Error'),
+        qr/^Caught exception/,
+        'Catalyst Error'
+    );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/errors/two'),
+        'Request' );
+    ok( $response->is_error, 'Response Server Error 5xx' );
+    is( $response->code,         500,         'Response Code' );
+    is( $response->content_type, 'text/html', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/errors/two', 'Test Action' );
+    like(
+        $response->header('X-Catalyst-Error'),
+        qr/^Couldn't forward to/,
+        'Catalyst Error'
+    );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/errors/three'),
+        'Request' );
+    ok( $response->is_error, 'Response Server Error 5xx' );
+    is( $response->code,         500,         'Response Code' );
+    is( $response->content_type, 'text/html', 'Response Content-Type' );
+    is(
+        $response->header('X-Catalyst-Action'),
+        'engine/response/errors/three',
+        'Test Action'
+    );
+    like(
+        $response->header('X-Catalyst-Error'),
+        qr/I'm going to die!/,
+        'Catalyst Error'
+    );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_headers.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_response_headers.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_headers.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_headers.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,58 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 18;
+use Catalyst::Test 'TestApp';
+use HTTP::Request::Common;
+
+my $content_length;
+
+foreach my $method qw(HEAD GET) {
+    my $expected = join( ', ', 1 .. 10 );
+
+    my $request = HTTP::Request::Common->can($method)
+        ->( 'http://localhost/engine/response/headers/one' );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->code, 200, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/headers/one', 'Test Action' );
+    is( $response->header('X-Header-Catalyst'),
+        'Cool', 'Response Header X-Header-Catalyst' );
+    is( $response->header('X-Header-Cool'),
+        'Catalyst', 'Response Header X-Header-Cool' );
+    is( $response->header('X-Header-Numbers'),
+        $expected, 'Response Header X-Header-Numbers' );
+
+    use bytes;
+    if ( $method eq 'HEAD' ) {
+        $content_length = $response->header('Content-Length');
+        ok( $content_length > 0, 'Response Header Content-Length' );
+        is( length($response->content),
+            0,
+            'HEAD method content is empty' );
+    }
+    elsif ( $method eq 'GET' ) {
+        # method name is echo'd back in content-body, which
+        # accounts for difference in content length.  In normal
+        # cases the Content-Length should be the same regardless
+        # of if its a GET or HEAD request.
+        SKIP:
+        {
+            if ( $ENV{CATALYST_SERVER} ) {
+                skip "Using remote server", 2;
+            }
+            is( $response->header('Content-Length'),
+                $content_length - 1, 'Response Header Content-Length' );
+            is( length($response->content),
+                $response->header('Content-Length'),
+                'GET method content' );
+        }
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_large.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_response_large.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_large.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_large.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,26 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 6;
+use Catalyst::Test 'TestApp';
+
+# phaylon noticed that refactored was truncating output on large images.
+# This test tests 100K and 1M output content.
+
+my $expected = {
+    one => 'x' x (100 * 1024),
+    two => 'y' x (1024 * 1024),
+};
+
+for my $action ( keys %{$expected} ) {
+    ok( my $response = request('http://localhost/engine/response/large/' . $action ),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+
+    is( length( $response->content ), length( $expected->{$action} ), 'Length OK' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_redirect.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_response_redirect.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_redirect.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_redirect.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,48 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 26;
+use Catalyst::Test 'TestApp';
+
+{
+    ok( my $response = request('http://localhost/engine/response/redirect/one'), 'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 302, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/one', 'Test Action' );
+    is( $response->header('Location'), '/test/writing/is/boring', 'Response Header Location' );
+    ok( $response->header('Content-Length'), '302 Redirect contains Content-Length' );
+    ok( $response->content, '302 Redirect contains a response body' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/redirect/two'), 'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 302, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/two', 'Test Action' );
+    is( $response->header('Location'), 'http://www.google.com/', 'Response Header Location' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/redirect/three'), 'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 301, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/three', 'Test Action' );
+    is( $response->header('Location'), 'http://www.google.com/', 'Response Header Location' );
+    ok( $response->header('Content-Length'), '301 Redirect contains Content-Length' );
+    ok( $response->content, '301 Redirect contains a response body' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/redirect/four'), 'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 307, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/four', 'Test Action' );
+    is( $response->header('Location'), 'http://www.google.com/', 'Response Header Location' );
+    ok( $response->header('Content-Length'), '307 Redirect contains Content-Length' );
+    ok( $response->content, '307 Redirect contains a response body' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_status.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_response_status.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_status.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_response_status.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,55 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 30;
+use Catalyst::Test 'TestApp';
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s200'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->code, 200, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s200', 'Test Action' );
+    like( $response->content, qr/^200/, 'Response Content' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s400'), 'Request' );
+    ok( $response->is_error, 'Response Client Error 4xx' );
+    is( $response->code, 400, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s400', 'Test Action' );
+    like( $response->content, qr/^400/, 'Response Content' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s403'), 'Request' );
+    ok( $response->is_error, 'Response Client Error 4xx' );
+    is( $response->code, 403, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s403', 'Test Action' );
+    like( $response->content, qr/^403/, 'Response Content' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s404'), 'Request' );
+    ok( $response->is_error, 'Response Client Error 4xx' );
+    is( $response->code, 404, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s404', 'Test Action' );
+    like( $response->content, qr/^404/, 'Response Content' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s500'), 'Request' );
+    ok( $response->is_error, 'Response Server Error 5xx' );
+    is( $response->code, 500, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s500', 'Test Action' );
+    like( $response->content, qr/^500/, 'Response Content' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_setup_basics.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_setup_basics.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_setup_basics.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_setup_basics.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,19 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 1;
+use Catalyst::Test 'TestApp';
+
+SKIP:
+{
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip "Using remote server", 1;
+    }
+    # Allow overriding automatic root.
+    is( TestApp->config->{root}, '/some/dir' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_engine_setup_plugins.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_engine_setup_plugins.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_engine_setup_plugins.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_engine_setup_plugins.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,16 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 2;
+use Catalyst::Test 'TestApp';
+
+{
+  # Allow overriding automatic root.
+    ok( my $response = request('http://localhost/engine/response/headers/one'), 'Request' );
+    is( $response->header('X-Catalyst-Plugin-Setup'), '1' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_fork.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_fork.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_fork.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_fork.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+# live_fork.t
+# Copyright (c) 2006 Jonathan Rockway <jrockway at cpan.org>
+
+=head1 SYNOPSIS
+
+Tests if Catalyst can fork/exec other processes successfully
+
+=cut
+use strict;
+use warnings;
+use Test::More;
+use YAML;
+use FindBin;
+use lib "$FindBin::Bin/lib";
+use Catalyst::Test qw(TestApp);
+
+plan skip_all => 'Using remote server'
+    if $ENV{CATALYST_SERVER};
+
+plan skip_all => 'Skipping fork tests: no /bin/ls'
+    if !-e '/bin/ls'; # see if /bin/ls exists
+
+plan tests => 13; # otherwise
+
+{
+  system:
+    ok(my $result = get('/fork/system/%2Fbin%2Fls'), 'system');
+    my @result = split /$/m, $result;
+    $result = join q{}, @result[-4..-1];
+
+    my $result_ref = eval { Load($result) };
+    ok($result_ref, 'is YAML');
+    is($result_ref->{result}, 0, 'exited OK');
+}
+
+{
+  backticks:
+    ok(my $result = get('/fork/backticks/%2Fbin%2Fls'), '`backticks`');
+    my @result = split /$/m, $result;
+    $result = join q{}, @result[-4..-1];
+
+    my $result_ref = eval { Load($result) };
+    ok($result_ref, 'is YAML');
+    is($result_ref->{code}, 0, 'exited successfully');
+    like($result_ref->{result}, qr{^/bin/ls[^:]}, 'contains ^/bin/ls$');
+    like($result_ref->{result}, qr{\n.*\n}m, 'contains two newlines');
+}
+{
+  fork:
+    ok(my $result = get('/fork/fork'), 'fork');
+    my @result = split /$/m, $result;
+    $result = join q{}, @result[-4..-1];
+
+    my $result_ref = eval { Load($result) };
+    ok($result_ref, 'is YAML');
+    isnt($result_ref->{pid}, 0, q{fork's "pid" wasn't 0});
+    isnt($result_ref->{pid}, $$, 'fork got a new pid');
+    is($result_ref->{result}, 'ok', 'fork was effective');
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_loop.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_loop.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_loop.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_loop.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,23 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 3;
+use Catalyst::Test 'TestApp';
+
+SKIP:
+{
+    # Net::HTTP::Methods crashes when talking to a remote server because this
+    # test causes a very long header line to be sent
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip 'Using remote server', 3;
+    }
+
+    ok( my $response = request('http://localhost/loop_test'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( $response->header('X-Class-Forward-Test-Method'), 'Loop OK' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_plugin_loaded.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_plugin_loaded.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_plugin_loaded.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_plugin_loaded.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,23 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 5;
+use Catalyst::Test 'TestApp';
+
+my @expected = qw[
+    Catalyst::Plugin::Test::Errors Catalyst::Plugin::Test::Headers Catalyst::Plugin::Test::Inline Catalyst::Plugin::Test::MangleDollarUnderScore Catalyst::Plugin::Test::Plugin TestApp::Plugin::AddDispatchTypes TestApp::Plugin::FullyQualified
+];
+
+my $expected = join( ", ", @expected );
+
+ok( my $response = request('http://localhost/dump/request'), 'Request' );
+ok( $response->is_success, 'Response Successful 2xx' );
+is( $response->content_type, 'text/plain', 'Response Content-Type' );
+like( $response->content, qr/'Catalyst::Request'/,
+    'Content is a serialized Catalyst::Request' );
+is( $response->header('X-Catalyst-Plugins'), $expected, 'Loaded plugins' );

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_priorities.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_priorities.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_priorities.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_priorities.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,80 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 28;
+use Catalyst::Test 'TestApp';
+use Data::Dumper;
+
+local $^W = 0;
+
+my $uri_base = 'http://localhost/priorities';
+my @tests = (
+
+    #   Simple
+    'Regex vs. Local',      { path => '/re_vs_loc',      expect => 'local' },
+    'Regex vs. LocalRegex', { path => '/re_vs_locre',    expect => 'regex' },
+    'Regex vs. Path',       { path => '/re_vs_path',     expect => 'path' },
+    'Local vs. LocalRegex', { path => '/loc_vs_locre',   expect => 'local' },
+    'Local vs. Path 1',     { path => '/loc_vs_path1',   expect => 'local' },
+    'Local vs. Path 2',     { path => '/loc_vs_path2',   expect => 'path' },
+    'Path  vs. LocalRegex', { path => '/path_vs_locre',  expect => 'path' },
+
+    #   index
+    'index vs. Regex',      { path => '/re_vs_index',    expect => 'index' },
+    'index vs. Local',      { path => '/loc_vs_index',   expect => 'index' },
+    'index vs. LocalRegex', { path => '/locre_vs_index', expect => 'index' },
+    'index vs. Path',       { path => '/path_vs_index',  expect => 'index' },
+
+    'multimethod zero',     { path => '/multimethod',    expect => 'zero' },
+    'multimethod one',      { path => '/multimethod/1',  expect => 'one 1' },
+    'multimethod two',      { path => '/multimethod/1/2',
+                                                         expect => 'two 1 2' },
+);
+
+while ( @tests ) {
+
+    my $name = shift @tests;
+    my $data = shift @tests;
+
+    #   Run tests for path with trailing slash and without
+  SKIP: for my $req_uri
+    (
+        join( '' => $uri_base, $data->{ path } ),      # Without trailing path
+        join( '' => $uri_base, $data->{ path }, '/' ), # With trailing path
+    ) {
+        my $end_slash = ( $req_uri =~ qr(/$) ? 1 : 0 );
+
+        #   use slash_expect argument if URI ends with slash
+        #   and the slash_expect argument is defined
+        my $expect = $data->{ expect } || '';
+        if ( $end_slash and exists $data->{ slash_expect } ) {
+            $expect = $data->{ slash_expect };
+        }
+
+        #   Call the URI on the TestApp
+        my $response = request( $req_uri );
+
+        #   Leave expect out to see the result
+        unless ( $expect ) {
+            skip 'Nothing expected, winner is ' . $response->content, 1;
+        }
+
+        #   Show error if response was no success
+        if ( not $response->is_success ) {
+            diag 'Error: ' . $response->headers->{ 'x-catalyst-error' };
+        }
+
+        #   Test if content matches expectations.
+        #   TODO This might flood the screen with the catalyst please-come-later
+        #        page. So I don't know it is a good idea.
+        is( $response->content, $expect,
+            "$name: @{[ $data->{ expect } ]} wins"
+            . ( $end_slash ? ' (trailing slash)' : '' )
+        );
+    }
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/live_recursion.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/live_recursion.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/live_recursion.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/live_recursion.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,25 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More tests => 3;
+use Catalyst::Test 'TestApp';
+
+local $^W = 0;
+
+SKIP:
+{
+    # Net::HTTP::Methods crashes when talking to a remote server because this
+    # test causes a very long header line to be sent
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip 'Using remote server', 3;
+    }
+
+    ok( my $response = request('http://localhost/recursion_test'), 'Request' );
+    ok( !$response->is_success, 'Response Not Successful' );
+    is( $response->header('X-Catalyst-Error'), 'Deep recursion detected calling "/recursion_test"', 'Deep Recursion Detected' );
+}

Copied: Catalyst-Engine-Apache/trunk/xt/author/notabs.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/notabs.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/notabs.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/notabs.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,9 @@
+use strict;
+use warnings;
+
+use File::Spec;
+use FindBin ();
+use Test::More;
+use Test::NoTabs;
+
+all_perl_files_ok(qw/lib/);

Copied: Catalyst-Engine-Apache/trunk/xt/author/pod.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/pod.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/pod.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/pod.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,7 @@
+use strict;
+use warnings;
+use Test::More;
+
+use Test::Pod 1.14;
+
+all_pod_files_ok();

Copied: Catalyst-Engine-Apache/trunk/xt/author/podcoverage.t (from rev 13639, Catalyst-Engine-Apache/trunk/t/author/podcoverage.t)
===================================================================
--- Catalyst-Engine-Apache/trunk/xt/author/podcoverage.t	                        (rev 0)
+++ Catalyst-Engine-Apache/trunk/xt/author/podcoverage.t	2010-10-04 22:34:18 UTC (rev 13640)
@@ -0,0 +1,15 @@
+use strict;
+use warnings;
+use Test::More;
+
+use Pod::Coverage 0.19;
+use Test::Pod::Coverage 1.04;
+
+my @modules = all_modules;
+our @private = ( 'BUILD' );
+foreach my $module (@modules) {
+    local @private = (@private, 'run') if $module =~ /^Catalyst::Script::/;
+    pod_coverage_ok($module, { also_private => \@private });
+}
+
+done_testing;




More information about the Catalyst-commits mailing list