Merge 'trunk' into 'more_metaclass_compat'
Tomas Doran [Thu, 20 May 2010 20:31:35 +0000 (20:31 +0000)]
r13205@t0mlaptop (orig r13169):  t0m | 2010-04-19 03:40:24 +0100
Document the action config here, as people don't seem to find it and this may help..
r13206@t0mlaptop (orig r13170):  t0m | 2010-04-19 03:41:57 +0100
Bah, accidentally removed..
r13207@t0mlaptop (orig r13171):  t0m | 2010-04-19 08:22:49 +0100
Go away useless warning
r13213@t0mlaptop (orig r13177):  ajgb | 2010-04-21 12:10:51 +0100
Fix not stripping backslashes in DispatchType::Regex::uri_for_action
r15483@t0mlaptop (orig r13190):  rafl | 2010-04-28 23:54:04 +0100
Make sure path_to returns an instance of the right Path::Class class.
r15484@t0mlaptop (orig r13191):  edenc | 2010-04-29 00:29:02 +0100
minor documentation fix for handle_request
r15489@t0mlaptop (orig r13193):  rafl | 2010-05-03 00:16:25 +0100
Allow parameterized roles to be applied as plugins.
r15490@t0mlaptop (orig r13194):  t0m | 2010-05-03 00:27:43 +0100
Back out crazy heuristics
r15492@t0mlaptop (orig r13196):  rafl | 2010-05-03 00:44:30 +0100
Unbreak tests by actually adding the module they're supposed to test.
r15494@t0mlaptop (orig r13198):  rafl | 2010-05-03 01:51:43 +0100
Remove useless conditional.
r15515@t0mlaptop (orig r13219):  wreis | 2010-05-06 13:34:10 +0100
make uri_for a bit cleaner
r15516@t0mlaptop (orig r13220):  wreis | 2010-05-06 14:30:19 +0100
minor fix for Changes file | add me as a contributor
r15517@t0mlaptop (orig r13221):  rafl | 2010-05-07 22:11:10 +0100
Pass along options to load_class for plugins.
r15518@t0mlaptop (orig r13222):  rafl | 2010-05-07 22:48:51 +0100
Changelogging.
r15519@t0mlaptop (orig r13223):  rafl | 2010-05-07 23:06:26 +0100
Version 5.80023.
r15535@t0mlaptop (orig r13239):  ribasushi | 2010-05-12 12:48:40 +0100
Better stats API explanation (SpiceMan)
r15559@t0mlaptop (orig r13263):  t0m | 2010-05-15 10:42:58 +0100
 r13208@spaceinvaders (orig r13172):  t0m | 2010-04-19 09:54:56 +0200
 Branch to try and fix the request uri stuff.

 r13209@spaceinvaders (orig r13173):  t0m | 2010-04-19 09:58:37 +0200
 Just add comments to tests, no functional changes
 r13210@spaceinvaders (orig r13174):  t0m | 2010-04-19 09:59:14 +0200
 Get it mostly working, except uri_for is still buggered
 r15488@spaceinvaders (orig r13192):  t0m | 2010-05-03 00:26:22 +0200
 Revert to old behaviour, allow config for new behaviour. Config option name is rubbish, needs fixing
 r15532@spaceinvaders (orig r13236):  t0m | 2010-05-09 01:09:01 +0200
 I hate this name less. Others may feel differently
 r15556@spaceinvaders (orig r13260):  t0m | 2010-05-15 10:52:16 +0200
 Simplify madness some more, back to how it looked in the original fix_path_info_decoding branch so that we aren't using dodgy heuristics to determine the path. Alter the prepare_path tests so that they're testing the appropriate config option so that we now have tests for both code paths
 r15557@spaceinvaders (orig r13261):  t0m | 2010-05-15 11:20:16 +0200
 Add a pile of docs for the new use_request_uri_for_path setting
 r15558@spaceinvaders (orig r13262):  t0m | 2010-05-15 11:38:06 +0200
 Add recommendation

r15560@t0mlaptop (orig r13264):  t0m | 2010-05-15 10:55:07 +0100
Changelog, bump versions, add new contributor :)
r15567@t0mlaptop (orig r13271):  jhannah | 2010-05-19 23:36:21 +0100
We appear to have a bug where if lazy => 1 isn't set an exception
occurs.

r15575@t0mlaptop (orig r13279):  jhannah | 2010-05-20 20:46:31 +0100
Oops. I should have TODO'd this one.  rafl++

18 files changed:
Changes
Makefile.PL
lib/Catalyst.pm
lib/Catalyst/Controller.pm
lib/Catalyst/DispatchType/Regex.pm
lib/Catalyst/Engine/CGI.pm
lib/Catalyst/Runtime.pm
t/aggregate/live_component_controller_args.t
t/aggregate/unit_core_ctx_attr.t [new file with mode: 0644]
t/aggregate/unit_core_engine_cgi-prepare_path.t
t/aggregate/unit_core_path_to.t
t/aggregate/unit_core_plugin.t
t/aggregate/unit_core_uri_for_action.t
t/lib/PluginTestApp.pm
t/lib/PluginTestApp/Controller/Root.pm
t/lib/TestApp.pm
t/lib/TestApp/Controller/Action/Regexp.pm
t/lib/TestApp/Plugin/ParameterizedRole.pm [new file with mode: 0644]

diff --git a/Changes b/Changes
index 2ec5d69..fe66038 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,9 +1,27 @@
 # This file documents the revision history for Perl extension Catalyst.
 
+5.80024 2010-05-15 11:55:44
+
+  Bug fixes:
+   - Revert the path resolution behaviour to how it used to work before
+     Catalyst 5.80014_02, so that application paths are (by default)
+     resolved from $ENV{PATH_INFO} and $ENV{SCRIPT_NAME}. This fixes backward
+     compatibility breakage seen by a number of people since that release
+     with mod_rewrite and SSI.
+
+  New features:
+   - Add a use_request_uri_for_path config setting to optionally
+     use the (more correct) $ENV{REQUEST_URI} path resolution behaviour.
+
+  Documentation:
+   - Clarify the documentation for the Catalyst::Stats interface.
+   - Copious documentation about the use_request_uri_for_path feature
+     and the implications of setting this to true/false in
+     Catalyst::Engine::CGI
+
+5.80023 2010-05-07 23:50:27
+
   Bug fixes:
-   - Additional fix for getting the base application path right when rewriting
-     requests into an application sub path with mod_alias and mod_rewrite on
-     Apache.
    - Ensure to always cleanup temporary uploaded files in all cases, even
      when exceptions occur during request processing, using HTTP::Body's
      ->cleanup feature. (RT#41442)
@@ -11,6 +29,7 @@
      dereferencing it. (RT#49267)
    - Fix regex special characters in REDIRECT_URL variable breaking
      the request base. (2nd part of RT#24951)
+   - Fix not stripping backslashes in DispatchType::Regex::uri_for_action
 
   New features:
    - Setting __PACKAGE__->config(enable_catalyst_header => 1); in your MyApp.pm
      HttpOnly flag
    - Allow the myapp_test.pl script to be given a list of paths which it
      will retrieve all of. (RT#53653)
+   - Allow parameterized roles to be applied as plugins.
+   - Allow requiring minimum versions of plugins when loading them.
 
   Documentation:
    - The Catalyst::Test::get method is documented as returning the raw
      response bytes without any character decoding (RT#53678)
 
+  Cleanups:
+   - Removal of $Catalyst::PRETTY_VERSION. Future releases will always have the
+     full and unmangled version number, including trailing zeroes, in
+     $Catalyst::VERSION.
+
 5.80022 2010-03-28 19:43:01
 
   New features:
@@ -54,7 +80,7 @@
 5.80021 2010-03-03 23:02:01
 
   Bug fixed:
-   - $c->uri_for will now escape unsafe characterss in captures
+   - $c->uri_for will now escape unsafe characters in captures
      ($c->request->captures) and correctly encode utf8 charracters.
 
 5.80020 2010-02-04 06:51:18
index c71fa40..3b2305c 100644 (file)
@@ -19,13 +19,14 @@ requires 'namespace::clean' => '0.13';
 requires 'B::Hooks::EndOfScope' => '0.08';
 requires 'MooseX::Emulate::Class::Accessor::Fast' => '0.00903';
 requires 'Class::MOP' => '0.95';
-requires 'Moose' => '0.93';
+requires 'Moose' => '1.03';
 requires 'MooseX::MethodAttributes::Inheritable' => '0.19';
 requires 'MooseX::Role::WithOverloading' => '0.05';
 requires 'Carp';
 requires 'Class::C3::Adopt::NEXT' => '0.07';
 requires 'CGI::Simple::Cookie' => '1.109';
 requires 'Data::Dump';
+requires 'Data::OptList';
 requires 'HTML::Entities';
 requires 'HTTP::Body'    => '1.06'; # ->cleanup(1)
 requires 'HTTP::Headers' => '1.64';
index f51bfb4..26b7649 100644 (file)
@@ -14,6 +14,7 @@ use Catalyst::Request::Upload;
 use Catalyst::Response;
 use Catalyst::Utils;
 use Catalyst::Controller;
+use Data::OptList;
 use Devel::InnerPackage ();
 use File::stat;
 use Module::Pluggable::Object ();
@@ -78,7 +79,7 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.80022';
+our $VERSION = '5.80024';
 
 sub import {
     my ( $class, @arguments ) = @_;
@@ -280,14 +281,15 @@ Specifies a comma-delimited list of log levels.
 
 =head2 -Stats
 
-Enables statistics collection and reporting. You can also force this setting
-from the system environment with CATALYST_STATS or <MYAPP>_STATS. The
-environment settings override the application, with <MYAPP>_STATS having the
-highest priority.
+Enables statistics collection and reporting.
 
-e.g.
+   use Catalyst qw/-Stats=1/;
 
-   use Catalyst qw/-Stats=1/
+You can also force this setting from the system environment with CATALYST_STATS
+or <MYAPP>_STATS. The environment settings override the application, with
+<MYAPP>_STATS having the highest priority.
+
+Stats are also enabled if L<< debugging |/"-Debug" >> is enabled.
 
 =head1 METHODS
 
@@ -1279,13 +1281,11 @@ sub uri_for {
     carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
     foreach my $arg (@args) {
         utf8::encode($arg) if utf8::is_utf8($arg);
-    }
-    s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
-    if (blessed $path) { # Action object only.
-        s|/|%2F|g for @args;
+        $arg =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
     }
 
     if ( blessed($path) ) { # action object
+        s|/|%2F|g for @args;
         my $captures = [ map { s|/|%2F|g; $_; }
                         ( scalar @args && ref $args[0] eq 'ARRAY'
                          ? @{ shift(@args) }
@@ -1306,8 +1306,6 @@ sub uri_for {
         $path = '/' if $path eq '';
     }
 
-    undef($path) if (defined $path && $path eq '');
-
     unshift(@args, $path);
 
     unless (defined $path && $path =~ s!^/!!) { # in-place strip
@@ -1890,7 +1888,7 @@ namespaces.
 
 sub get_actions { my $c = shift; $c->dispatcher->get_actions( $c, @_ ) }
 
-=head2 $c->handle_request( $class, @arguments )
+=head2 $app->handle_request( @arguments )
 
 Called to handle each HTTP request.
 
@@ -2779,22 +2777,29 @@ the plugin name does not begin with C<Catalyst::Plugin::>.
         my ( $class, $plugins ) = @_;
 
         $class->_plugins( {} ) unless $class->_plugins;
-        $plugins ||= [];
+        $plugins = Data::OptList::mkopt($plugins || []);
 
-        my @plugins = Catalyst::Utils::resolve_namespace($class . '::Plugin', 'Catalyst::Plugin', @$plugins);
+        my @plugins = map {
+            [ Catalyst::Utils::resolve_namespace(
+                  $class . '::Plugin',
+                  'Catalyst::Plugin', $_->[0]
+              ),
+              $_->[1],
+            ]
+         } @{ $plugins };
 
         for my $plugin ( reverse @plugins ) {
-            Class::MOP::load_class($plugin);
-            my $meta = find_meta($plugin);
+            Class::MOP::load_class($plugin->[0], $plugin->[1]);
+            my $meta = find_meta($plugin->[0]);
             next if $meta && $meta->isa('Moose::Meta::Role');
 
-            $class->_register_plugin($plugin);
+            $class->_register_plugin($plugin->[0]);
         }
 
         my @roles =
-            map { $_->name }
-            grep { $_ && blessed($_) && $_->isa('Moose::Meta::Role') }
-            map { find_meta($_) }
+            map  { $_->[0]->name, $_->[1] }
+            grep { blessed($_->[0]) && $_->[0]->isa('Moose::Meta::Role') }
+            map  { [find_meta($_->[0]), $_->[1]] }
             @plugins;
 
         Moose::Util::apply_all_roles(
@@ -2808,15 +2813,24 @@ the plugin name does not begin with C<Catalyst::Plugin::>.
 Returns an arrayref of the internal execution stack (actions that are
 currently executing).
 
+=head2 $c->stats
+
+Returns the current timing statistics object. By default Catalyst uses
+L<Catalyst::Stats|Catalyst::Stats>, but can be set otherwise with
+L<< stats_class|/"$c->stats_class" >>.
+
+Even if L<< -Stats|/"-Stats" >> is not enabled, the stats object is still
+available. By enabling it with C< $c->stats->enabled(1) >, it can be used to
+profile explicitly, although MyApp.pm still won't profile nor output anything
+by itself.
+
 =head2 $c->stats_class
 
-Returns or sets the stats (timing statistics) class.
+Returns or sets the stats (timing statistics) class. L<Catalyst::Stats|Catalyst::Stats> is used by default.
 
 =head2 $c->use_stats
 
-Returns 1 when stats collection is enabled.  Stats collection is enabled
-when the -Stats options is set, debug is on or when the <MYAPP>_STATS
-environment variable is set.
+Returns 1 when L<< stats collection|/"-Stats" >> is enabled.
 
 Note that this is a static method, not an accessor and should be overridden
 by declaring C<sub use_stats { 1 }> in your MyApp.pm, not by calling C<< $c->use_stats(1) >>.
@@ -2914,6 +2928,12 @@ to be shown in hit debug tables in the test server.
 
 =item *
 
+C<use_request_uri_for_path> - Controlls if the C<REQUEST_URI> or C<PATH_INFO> environment
+variable should be used for determining the request path. See L<Catalyst::Engine::CGI/PATH DECODING>
+for more information.
+
+=item *
+
 C<using_frontend_proxy> - See L</PROXY SUPPORT>.
 
 =back
@@ -3143,6 +3163,8 @@ random: Roland Lammel <lammel@cpan.org>
 
 Robert Sedlacek C<< <rs@474.at> >>
 
+SpiceMan: Marcel Montes
+
 sky: Arthur Bergman
 
 szbalint: Balint Szilakszi <szbalint@cpan.org>
@@ -3157,6 +3179,8 @@ Will Hawes C<info@whawes.co.uk>
 
 willert: Sebastian Willert <willert@cpan.org>
 
+wreis: Wallace Reis <wallace@reis.org.br>
+
 Yuval Kogman, C<nothingmuch@woobling.org>
 
 =head1 LICENSE
index 9f52b3f..fbc8768 100644 (file)
@@ -446,11 +446,31 @@ of setting namespace to '' (the null string).
 
 Sets 'path_prefix', as described below.
 
+=head2 action
+
+Allows you to set the attributes that the dispatcher creates actions out of.
+This allows you to do 'rails style routes', or override some of the
+attribute defintions of actions composed from Roles.
+You can set arguments globally (for all actions of the controller) and
+specifically (for a single action).
+
+    __PACKAGE__->config(
+        action => {
+            '*' => { Chained => 'base', Args => 0  },
+            base => { Chained => '/', PathPart => '', CaptureArgs => 0 },
+        },
+     );
+
+In the case above every sub in the package would be made into a Chain
+endpoint with a URI the same as the sub name for each sub, chained
+to the sub named C<base>. Ergo dispatch to C</example> would call the
+C<base> method, then the C<example> method.
+
 =head2 action_args
 
 Allows you to set constructor arguments on your actions. You can set arguments
-globally (for all actions of the controller) and specifically (for a single
-action). This is particularly useful when using C<ActionRole>s
+globally and specifically (as above).
+This is particularly useful when using C<ActionRole>s
 (L<Catalyst::Controller::ActionRole>) and custom C<ActionClass>es.
 
     __PACKAGE__->config(
index 0d6da04..4b1beae 100644 (file)
@@ -151,6 +151,7 @@ sub uri_for_action {
             my $re = "$orig";
             $re =~ s/^\^//;
             $re =~ s/\$$//;
+            $re =~ s/\\([^\\])/$1/g;
             my $final = '/';
             my @captures = @$captures;
             while (my ($front, $rest) = split(/\(/, $re, 2)) {
index f9f9fa8..0617742 100644 (file)
@@ -28,6 +28,43 @@ appropriate engine module.
 
 This is the Catalyst engine specialized for the CGI environment.
 
+=head1 PATH DECODING
+
+Most web server environments pass the requested path to the application using environment variables,
+from which Catalyst has to reconstruct the request base (i.e. the top level path to / in the application,
+exposed as C<< $c->request->base >>) and the request path below that base.
+
+There are two methods of doing this, both of which have advantages and disadvantages. Which method is used
+is determined by the C<< $c->config(use_request_uri_for_path) >> setting (which can either be true or false).
+
+=head2 use_request_uri_for_path => 0
+
+This is the default (and the) traditional method that Catalyst has used for determining the path information.
+The path is synthesised from a combination of the C<PATH_INFO> and C<SCRIPT_NAME> environment variables.
+The allows the application to behave correctly when C<mod_rewrite> is being used to redirect requests
+into the application, as these variables are adjusted by mod_rewrite to take account for the redirect.
+
+However this method has the major disadvantage that it is impossible to correctly decode some elements
+of the path, as RFC 3875 says: "C<< Unlike a URI path, the PATH_INFO is not URL-encoded, and cannot
+contain path-segment parameters. >>" This means PATH_INFO is B<always> decoded, and therefore Catalyst
+can't distinguish / vs %2F in paths (in addition to other encoded values).
+
+=head2 use_request_uri_for_path => 1
+
+This method uses the C<REQUEST_URI> and C<SCRIPT_NAME> environment variables. As C<REQUEST_URI> is never
+decoded, this means that applications using this mode can correctly handle URIs including the %2F character
+(i.e. with C<AllowEncodedSlashes> set to C<On> in Apache).
+
+Given that this method of path resolution is provably more correct, it is recommended that you use
+this unless you have a specific need to deploy your application in a non-standard environment, and you are
+aware of the implications of not being able to handle encoded URI paths correctly.
+
+However it also means that in a number of cases when the app isn't installed directly at a path, but instead
+is having paths rewritten into it (e.g. as a .cgi/fcgi in a public_html directory, with mod_rewrite in a
+.htaccess file, or when SSI is used to rewrite pages into the app, or when sub-paths of the app are exposed
+at other URIs than that which the app is 'normally' based at with C<mod_rewrite>), the resolution of
+C<< $c->request->base >> will be incorrect.
+
 =head1 OVERLOADED METHODS
 
 This class overloads some methods from C<Catalyst::Engine>.
@@ -128,7 +165,6 @@ sub prepare_path {
     else {
         $base_path = $script_name || '/';
     }
-#    $base_path .= '/' unless $base_path =~ m{/$};
 
     # If we are running as a backend proxy, get the true hostname
   PROXY_CHECK:
@@ -149,25 +185,19 @@ sub prepare_path {
         }
     }
 
-    # RFC 3875: "Unlike a URI path, the PATH_INFO is not URL-encoded,
-    # and cannot contain path-segment parameters." This means PATH_INFO
-    # is always decoded, and the script can't distinguish / vs %2F.
-    # See https://issues.apache.org/bugzilla/show_bug.cgi?id=35256
-    # Here we try to resurrect the original encoded URI from REQUEST_URI.
     my $path_info   = $ENV{PATH_INFO};
-    if (my $req_uri = $ENV{REQUEST_URI}) {
-        $req_uri =~ s/^\Q$base_path\E//;
-        $req_uri =~ s/\?.*$//;
-        if ($req_uri && $req_uri ne '/') {
-            # This means that REQUEST_URI needs information from PATH_INFO
-            # prepending to it to be useful, otherwise the sub path which is
-            # being redirected to becomes the app base address which is
-            # incorrect.
-            my ($match) = $req_uri =~ m{^(/?[^/]+)};
-            my ($path_info_part) = $path_info =~ m|^(.*?\Q$match\E)|;
-            substr($req_uri, 0, length($match), $path_info_part)
-                if $path_info_part;
-            $path_info = $req_uri;
+    if ($c->config->{use_request_uri_for_path}) {
+        # RFC 3875: "Unlike a URI path, the PATH_INFO is not URL-encoded,
+        # and cannot contain path-segment parameters." This means PATH_INFO
+        # is always decoded, and the script can't distinguish / vs %2F.
+        # See https://issues.apache.org/bugzilla/show_bug.cgi?id=35256
+        # Here we try to resurrect the original encoded URI from REQUEST_URI.
+        if (my $req_uri = $ENV{REQUEST_URI}) {
+            if (defined $script_name) {
+                $req_uri =~ s/^\Q$script_name\E//;
+            }
+            $req_uri =~ s/\?.*$//;
+            $path_info = $req_uri if $req_uri;
         }
     }
 
index f9853ec..0c37ca2 100644 (file)
@@ -7,7 +7,7 @@ BEGIN { require 5.008004; }
 
 # Remember to update this in Catalyst as well!
 
-our $VERSION='5.80022';
+our $VERSION = '5.80024';
 
 =head1 NAME
 
index 29d26a1..93b757c 100644 (file)
@@ -73,15 +73,15 @@ sub run_test_for {
 
         my $response;
 
-        ok( $response = request("http://localhost/args/args/$path"), "Requested args for path $path");
+        ok( $response = request("http://localhost/args/args/$path"), "Requested /args/args/$path");
 
         is( $response->content, $test, "$test as args" );
 
         undef $response;
 
-        ok( $response = request("http://localhost/args/params/$path"), "Requested params for path $path");
+        ok( $response = request("http://localhost/args/params/$path"), "Requested /args/params/$path");
 
-        is( $response->content, $test, "$test as params" );
+        is( $response->content, $test, "response content $test as params" );
 
         undef $response;
 
diff --git a/t/aggregate/unit_core_ctx_attr.t b/t/aggregate/unit_core_ctx_attr.t
new file mode 100644 (file)
index 0000000..219600f
--- /dev/null
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+use FindBin qw/$Bin/;
+use lib "$FindBin::Bin/../lib";
+use Test::More;
+use URI;
+
+use_ok('TestApp');
+
+my $request = Catalyst::Request->new( {
+                base => URI->new('http://127.0.0.1/foo')
+              } );
+my $dispatcher = TestApp->dispatcher;
+my $context = TestApp->new( {
+                request => $request,
+                namespace => 'yada',
+              } );
+
+is(        $context->hello_lazy,    'hello there', '$context->hello_lazy');
+eval { is( $context->hello_notlazy, 'hello there', '$context->hello_notlazy') };
+TODO: {
+   local $TODO = 'we appear to have a lazy bug';
+   if ($@) {
+      fail('$context->hello_notlazy');
+      warn $@;
+   }
+}
+
+done_testing;
+
index c604487..d17cd98 100644 (file)
@@ -8,18 +8,18 @@ use Catalyst::Engine::CGI;
 
 # mod_rewrite to app root for non / based app
 {
-    my $r = get_req (
+    my $r = get_req (0,
         REDIRECT_URL => '/comics/',
         SCRIPT_NAME => '/comics/dispatch.cgi',
         REQUEST_URI => '/comics/',
     );
-    is ''.$r->uri, 'http://www.foo.com/comics/';
-    is ''.$r->base, 'http://www.foo.com/comics/';
+    is ''.$r->uri, 'http://www.foo.com/comics/', 'uri is correct';
+    is ''.$r->base, 'http://www.foo.com/comics/', 'base is correct';
 }
 
 # mod_rewrite to sub path under app root for non / based app
 {
-    my $r = get_req (
+    my $r = get_req (0,
         PATH_INFO  => '/foo/bar.gif',
         REDIRECT_URL => '/comics/foo/bar.gif',
         SCRIPT_NAME => '/comics/dispatch.cgi',
@@ -31,7 +31,7 @@ use Catalyst::Engine::CGI;
 
 # Standard CGI hit for non / based app
 {
-    my $r = get_req (
+    my $r = get_req (0,
         PATH_INFO => '/static/css/blueprint/screen.css',
         SCRIPT_NAME => '/~bobtfish/Gitalist/script/gitalist.cgi',
         REQUEST_URI => '/~bobtfish/Gitalist/script/gitalist.cgi/static/css/blueprint/screen.css',
@@ -41,19 +41,19 @@ use Catalyst::Engine::CGI;
 }
 # / %2F %252F escaping case.
 {
-    my $r = get_req (
+    my $r = get_req (1,
         PATH_INFO => '/%2F/%2F',
         SCRIPT_NAME => '/~bobtfish/Gitalist/script/gitalist.cgi',
         REQUEST_URI => '/~bobtfish/Gitalist/script/gitalist.cgi/%252F/%252F',
     );
-    is ''.$r->uri, 'http://www.foo.com/~bobtfish/Gitalist/script/gitalist.cgi/%252F/%252F';
-    is ''.$r->base, 'http://www.foo.com/~bobtfish/Gitalist/script/gitalist.cgi/';
+    is ''.$r->uri, 'http://www.foo.com/~bobtfish/Gitalist/script/gitalist.cgi/%252F/%252F', 'uri correct';
+    is ''.$r->base, 'http://www.foo.com/~bobtfish/Gitalist/script/gitalist.cgi/', 'base correct';
 }
 
 # Using rewrite rules to ask for a sub-path in your app.
 # E.g. RewriteRule ^(.*)$ /path/to/fastcgi/domainprofi.fcgi/iframeredirect$1 [L,NS]
 {
-    my $r = get_req (
+    my $r = get_req (0,
         PATH_INFO => '/iframeredirect/info',
         SCRIPT_NAME => '',
         REQUEST_URI => '/info',
@@ -64,7 +64,7 @@ use Catalyst::Engine::CGI;
 
 # nginx example from espent with path /"foo"
 {
-    my $r = get_req (
+    my $r = get_req (0,
         PATH_INFO => '"foo"',
         SCRIPT_NAME => '/',
         REQUEST_URI => '/%22foo%22',
@@ -76,32 +76,33 @@ use Catalyst::Engine::CGI;
 
 # nginx example from espent with path /"foo" and the app based at /oslobilder
 {
-    my $r = get_req (
+    my $r = get_req (1,
         PATH_INFO => 'oslobilder/"foo"',
         SCRIPT_NAME => '/oslobilder/',
         REQUEST_URI => '/oslobilder/%22foo%22',
     );
-    is ''.$r->path, '%22foo%22';
-    is ''.$r->uri, 'http://www.foo.com/oslobilder/%22foo%22';
-    is ''.$r->base, 'http://www.foo.com/oslobilder/';
+    is ''.$r->path, '%22foo%22', 'path correct';
+    is ''.$r->uri, 'http://www.foo.com/oslobilder/%22foo%22', 'uri correct';
+    is ''.$r->base, 'http://www.foo.com/oslobilder/', 'base correct';
 }
 
 {
-    my $r = get_req (
+    local $TODO = 'Another mod_rewrite case';
+    my $r = get_req (0,
         PATH_INFO => '/auth/login',
         SCRIPT_NAME => '/tx',
         REQUEST_URI => '/login',
     );
-    is ''.$r->path, 'auth/login';
-    is ''.$r->uri, 'http://www.foo.com/tx/auth/login';
-    is ''.$r->base, 'http://www.foo.com/tx/';
+    is ''.$r->path, 'auth/login', 'path correct';
+    is ''.$r->uri, 'http://www.foo.com/tx/auth/login', 'uri correct';
+    is ''.$r->base, 'http://www.foo.com/tx/', 'base correct';
 }
 
 # test req->base and c->uri_for work correctly after an internally redirected request
 # (i.e. REDIRECT_URL set) when the PATH_INFO contains a regex
 {
     my $path = '/engine/request/uri/Rx(here)';
-    my $r = get_req (
+    my $r = get_req (0,
         SCRIPT_NAME => '/',
         PATH_INFO => $path,
         REQUEST_URI => $path,
@@ -120,6 +121,8 @@ use Catalyst::Engine::CGI;
 #       - Test scheme (secure request on port 80)
 
 sub get_req {
+    my $use_request_uri_for_path = shift;
+
     my %template = (
         HTTP_HOST => 'www.foo.com',
         PATH_INFO => '/',
@@ -128,6 +131,9 @@ sub get_req {
     local %ENV = (%template, @_);
 
     my $i = TestApp->new;
+    $i->setup_finished(0);
+    $i->config(use_request_uri_for_path => $use_request_uri_for_path);
+    $i->setup_finished(1);
     $i->engine(Catalyst::Engine::CGI->new);
     $i->engine->prepare_path($i);
     return $i->req;
index a89135c..f4fe89f 100644 (file)
@@ -2,6 +2,9 @@ use strict;
 use warnings;
 
 use Test::More;
+use FindBin;
+use Path::Class;
+use File::Basename;
 
 my %non_unix = (
     MacOS   => 1,
@@ -16,17 +19,20 @@ my %non_unix = (
 
 my $os = $non_unix{$^O} ? $^O : 'Unix';
 
-if(  $os ne 'Unix' ) {
+if ( $os ne 'Unix' ) {
     plan skip_all => 'tests require Unix';
 }
-else {
-    plan tests => 3;
-}
 
 use_ok('Catalyst');
 
 my $context = 'Catalyst';
 
+$context->setup_home;
+my $base = dir($FindBin::Bin)->relative->stringify;
+
+isa_ok( Catalyst::path_to( $context, $base ), 'Path::Class::Dir' );
+isa_ok( Catalyst::path_to( $context, $base, basename $0 ), 'Path::Class::File' );
+
 my $config = Catalyst->config;
 
 $config->{home} = '/home/sri/my-app/';
@@ -37,3 +43,5 @@ $config->{home} = '/Users/sri/myapp/';
 
 is( Catalyst::path_to( $context, 'foo', 'bar' ),
     '/Users/sri/myapp/foo/bar', 'deep Unix path' );
+
+done_testing;
index 11cef84..16a5e24 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 24;
+use Test::More;
 
 use lib 't/lib';
 
@@ -61,3 +61,4 @@ my @expected = qw(
 is_deeply [ TestApp->registered_plugins ], \@expected,
   'registered_plugins() should only report the plugins for the current class';
 
+done_testing;
index 89079f9..ccc5910 100644 (file)
@@ -8,7 +8,7 @@ use lib "$FindBin::Bin/../lib";
 
 use Test::More;
 
-plan tests => 30;
+plan tests => 33;
 
 use_ok('TestApp');
 
@@ -21,8 +21,6 @@ my $private_action = $dispatcher->get_action_by_path(
                        '/class_forward_test_method'
                      );
 
-warn $dispatcher->uri_for_action($private_action);
-
 ok(!defined($dispatcher->uri_for_action($private_action)),
    "Private action returns undef for URI");
 
@@ -56,6 +54,21 @@ is($dispatcher->uri_for_action($regex_action, [ 'foo', 123 ]),
    "/action/regexp/foo/123",
    "Regex action interpolates captures correctly");
 
+my $regex_action_bs = $dispatcher->get_action_by_path(
+                     '/action/regexp/one_backslashes'
+                   );
+
+ok(!defined($dispatcher->uri_for_action($regex_action_bs)),
+   "Regex action without captures returns undef");
+
+ok(!defined($dispatcher->uri_for_action($regex_action_bs, [ 1, 2, 3 ])),
+   "Regex action with too many captures returns undef");
+
+is($dispatcher->uri_for_action($regex_action_bs, [ 'foo', 123 ]),
+   "/action/regexp/foo/123.html",
+   "Regex action interpolates captures correctly");
+
+
 #
 #   Index Action
 #
index 1031586..29a02cd 100644 (file)
@@ -1,10 +1,13 @@
 package PluginTestApp;
 use Test::More;
 
-use Catalyst qw(
-        Test::Plugin
-        +TestApp::Plugin::FullyQualified
-        );
+use Catalyst (
+    'Test::Plugin',
+    '+TestApp::Plugin::FullyQualified',
+    (eval { require MooseX::Role::Parameterized; 1 }
+        ? ('+TestApp::Plugin::ParameterizedRole' => { method_name => 'affe' })
+        : ()),
+);
 
 sub _test_plugins {
     my $c = shift;
index 5358074..7bec366 100644 (file)
@@ -34,6 +34,13 @@ sub run_time_plugins : Local {
     ref($c)->plugin( faux => $faux_plugin );
 
     isa_ok $c, 'Catalyst::Plugin::Test::Plugin';
+
+    # applied parameterized role
+    if (eval { require MooseX::Role::Parameterized; 1 }) {
+        can_ok $c, 'affe';
+        is $c->affe, 'birne', 'right method created by parameterized role';
+    }
+
     isa_ok $c, 'TestApp::Plugin::FullyQualified';
     ok !$c->isa($faux_plugin),
     '... and it should not inherit from the instant plugin';
index 3391a22..3bd3763 100644 (file)
@@ -16,9 +16,33 @@ use Catalyst::Utils;
 use Moose;
 use namespace::autoclean;
 
+# -----------
+# t/aggregate/unit_core_ctx_attr.t pukes until lazy is true
+package Greeting;
+use Moose;
+sub hello_notlazy { 'hello there' }
+sub hello_lazy    { 'hello there' }
+
+package TestApp;
+has 'my_greeting_obj_notlazy' => (
+   is      => 'ro',
+   isa     => 'Greeting',
+   default => sub { Greeting->new() },
+   handles => [ qw( hello_notlazy ) ],
+   lazy    => 0,
+);
+has 'my_greeting_obj_lazy' => (
+   is      => 'ro',
+   isa     => 'Greeting',
+   default => sub { Greeting->new() },
+   handles => [ qw( hello_lazy ) ],
+   lazy    => 1,
+);
+# -----------
+
 our $VERSION = '0.01';
 
-TestApp->config( name => 'TestApp', root => '/some/dir' );
+TestApp->config( name => 'TestApp', root => '/some/dir', use_request_uri_for_path => 1 );
 
 # Test bug found when re-adjusting the metaclass compat code in Moose
 # in 292360. Test added to Moose in 4b760d6, but leave this attribute
index 4b59d58..7966874 100644 (file)
@@ -27,4 +27,9 @@ sub four : Action Regex('^action/regexp/redirect/(\w+)/universe/(\d+)/everything
     );
 }
 
+sub one_backslashes : Action Regex('^action/regexp/(\w+)/(\d+)\.html$') {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
 1;
diff --git a/t/lib/TestApp/Plugin/ParameterizedRole.pm b/t/lib/TestApp/Plugin/ParameterizedRole.pm
new file mode 100644 (file)
index 0000000..f02d454
--- /dev/null
@@ -0,0 +1,18 @@
+package TestApp::Plugin::ParameterizedRole;
+
+use MooseX::Role::Parameterized;
+use namespace::autoclean;
+
+parameter method_name => (
+    isa      => 'Str',
+    required => 1,
+);
+
+role {
+    my $p = shift;
+    my $method_name = $p->method_name;
+
+    method $method_name => sub { 'birne' };
+};
+
+1;