[Catalyst-commits] r13307 - in Catalyst-Runtime/5.80/branches/psgi: . lib lib/Catalyst lib/Catalyst/DispatchType lib/Catalyst/Script script t/aggregate t/lib t/lib/PluginTestApp/Controller t/lib/TestApp/Action t/lib/TestApp/Controller/Action t/lib/TestApp/Model t/lib/TestApp/Plugin t/lib/TestAppEncoding/Controller

t0m at dev.catalyst.perl.org t0m at dev.catalyst.perl.org
Mon May 24 15:44:03 GMT 2010


Author: t0m
Date: 2010-05-24 16:44:03 +0100 (Mon, 24 May 2010)
New Revision: 13307

Added:
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/catalyst_test_utf8.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_component_generating.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_ctx_attr.t
   Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Action/TestExtraArgsAction.pm
   Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Model/Generating.pm
   Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Plugin/ParameterizedRole.pm
Modified:
   Catalyst-Runtime/5.80/branches/psgi/
   Catalyst-Runtime/5.80/branches/psgi/Changes
   Catalyst-Runtime/5.80/branches/psgi/Makefile.PL
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Component.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Controller.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Chained.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Index.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Regex.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Engine.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Runtime.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Script/Create.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Script/Test.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/ScriptRole.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Test.pm
   Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Upgrading.pod
   Catalyst-Runtime/5.80/branches/psgi/script/catalyst.pl
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_action_action.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_action_chained.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_args.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_path_to.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_plugin.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_cgi.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_fastcgi.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_server.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_test.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for_action.t
   Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for_multibytechar.t
   Catalyst-Runtime/5.80/branches/psgi/t/lib/PluginTestApp.pm
   Catalyst-Runtime/5.80/branches/psgi/t/lib/PluginTestApp/Controller/Root.pm
   Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp.pm
   Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Controller/Action/Action.pm
   Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Controller/Action/Regexp.pm
   Catalyst-Runtime/5.80/branches/psgi/t/lib/TestAppEncoding/Controller/Root.pm
Log:
 r15602 at spaceinvaders:  t0m | 2010-05-23 12:55:33 +0100
 Merge trunk into here, fix tests to pass again with the newer versions of Plack



Property changes on: Catalyst-Runtime/5.80/branches/psgi
___________________________________________________________________
Modified: svk:merge
   - 1c72fc7c-9ce4-42af-bf25-3bfe470ff1e8:/local/Catalyst/trunk/Catalyst-Runtime:9763
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.70/branches/compres:7999
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.70/branches/context_go:8001
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.70/trunk:8533
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/Catalyst-Test-Updates:8363
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/add_captures_to_visit:9546
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/aggregate_more:11803
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/better_scripts:12074
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/disable_regex_fallback:11456
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/fix_path_info_decoding:12089
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/index_default_fuckage:10646
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/moose:7911
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/namespace_handling_refactor:10655
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/uri_encode_captures_andor_args_take2:11811
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-ChildOf:4443
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-Runtime-jrockway:5857
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-component-setup:4320
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-docs:4325
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/current/Catalyst-Runtime:5142
4ad37cd2-5fec-0310-835f-b3785c72a374:/trunk/Catalyst:4483
4ad37cd2-5fec-0310-835f-b3785c72a374:/trunk/Catalyst-Runtime:6165
6d45476b-5895-46b8-b13a-8b969fa34c98:/local/Catalyst-Runtime-better_scripts:11331
8a9521aa-ff93-41d6-9f87-b05cafcdab40:/local/cat/Catalyst-Runtime/5.80/trunk:8157
d7608cd0-831c-0410-93c0-e5b306c3c028:/local/Catalyst/Catalyst-Runtime:8339
d7608cd0-831c-0410-93c0-e5b306c3c028:/local/Catalyst/Catalyst-Runtime-jrockway:8342
e56d974f-7718-0410-8b1c-b347a71765b2:/local/Catalyst-Runtime:6511
e56d974f-7718-0410-8b1c-b347a71765b2:/local/Catalyst-Runtime-current:10442
   + 1c72fc7c-9ce4-42af-bf25-3bfe470ff1e8:/local/Catalyst/trunk/Catalyst-Runtime:9763
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.70/branches/compres:7999
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.70/branches/context_go:8001
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.70/trunk:8533
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/Catalyst-Test-Updates:8363
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/add_captures_to_visit:9546
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/aggregate_more:11803
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/better_scripts:12074
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/disable_regex_fallback:11456
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/fix_path_info_decoding:12089
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/fix_request_uri:13262
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/index_default_fuckage:10646
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/moose:7911
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/more_metaclass_compat:13280
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/namespace_handling_refactor:10655
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/param_filtering:13012
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/uri_encode_captures_andor_args_take2:11811
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/branches/uri_for_utf8:12834
4ad37cd2-5fec-0310-835f-b3785c72a374:/Catalyst-Runtime/5.80/trunk:13297
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-ChildOf:4443
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-Runtime-jrockway:5857
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-component-setup:4320
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/Catalyst-docs:4325
4ad37cd2-5fec-0310-835f-b3785c72a374:/branches/current/Catalyst-Runtime:5142
4ad37cd2-5fec-0310-835f-b3785c72a374:/trunk/Catalyst:4483
4ad37cd2-5fec-0310-835f-b3785c72a374:/trunk/Catalyst-Runtime:6165
6d45476b-5895-46b8-b13a-8b969fa34c98:/local/Catalyst-Runtime-better_scripts:11331
6d45476b-5895-46b8-b13a-8b969fa34c98:/local/Catalyst-Runtime-mech_tests:15583
6d45476b-5895-46b8-b13a-8b969fa34c98:/local/Catalyst-Runtime-psgi:15602
8a9521aa-ff93-41d6-9f87-b05cafcdab40:/local/cat/Catalyst-Runtime/5.80/trunk:8157
d7608cd0-831c-0410-93c0-e5b306c3c028:/local/Catalyst/Catalyst-Runtime:8339
d7608cd0-831c-0410-93c0-e5b306c3c028:/local/Catalyst/Catalyst-Runtime-jrockway:8342
e56d974f-7718-0410-8b1c-b347a71765b2:/local/Catalyst-Runtime:6511
e56d974f-7718-0410-8b1c-b347a71765b2:/local/Catalyst-Runtime-current:10442

Modified: Catalyst-Runtime/5.80/branches/psgi/Changes
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/Changes	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/Changes	2010-05-24 15:44:03 UTC (rev 13307)
@@ -1,14 +1,140 @@
 # This file documents the revision history for Perl extension Catalyst.
 
+ Bug fixes:
+  - Fix the --mech and --mechanize options to the myapp_create.pl script
+    to operate correctly by fixing the options passed down into the script.
+
+ Documentation:
+  - Fix missing - in the docs when describing the --mechanize option at one
+    point.
+
+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:
+   - 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)
+   - Ensure that Catalyst::Engine::HTTP's options hash is defined before
+     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
+     now enables the X-Catalyst header being printed when not in debug mode.
+   - Require CGI::Simple::Cookie version 1.109 to ensure support for the
+     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:
+   - Log an extra line in debug mode with the response status code,
+     the content type and content length if available.
+
+  Refactoring / optimizations:
+   - Display of the end of hit debug messages has been factored out into
+     log_headers, log_request, log_request_headers, log_response,
+     log_response_status_line and log_response_headers methods so that
+     plugins which customise how much information is shown on the debug
+     screen as easy to write.
+   - Make all logging of request and response state get the information from
+     $c->dump_these so that there is a unified point from which to hook
+     in parameter filtering (for example).
+   - $c->model/view/controller have become a lot faster for non-regexp names
+     by using direct hash lookup instead of looping.
+   - IP address => hostname mapping for the server is only done once and cached
+     by Catalyst::Engine::HTTP to somewhat mitigate the problem of people
+     developing on machines pointed at slow DNS servers.
+
+  Bugs fixed:
+    - DispatchType::Index's uri_for_action only returns for actions registered
+      with it (prevents 'index :Path' or similar resolving to the wrong URI)
+    - Make sure to construct Upload objects properly, even if there are
+      multiple Content-Type headers (Closes RT#55976).
+
+5.80021 2010-03-03 23:02:01
+
+  Bug fixed:
+   - $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
+
+  New features:
+    - Allow components to specify additional components to be set up by
+      overriding the expand_modules method. (Oliver Charles)
+
+5.80019 2010-01-29 01:04:09
+
+  Bug fixed:
+   - Calls to $c->uri_for with private paths as strings (e.g.
+     $c->uri_for('controller/action', 'arg1', 'arg2') ) no longer have
+     / encoded to %2F. This is due to $c->uri_for('static', 'css/foo', $bar)
+     which should not be encoded.
+     Calls with an action object (rather than a string), or uri_for action
+     will still encode / in args and captures to %2F
+
+   - The above noted / => %2F encoding in uri_for_action or uri_for with
+     an action object has been fixed to not just encode the first slash in
+     any set of args/captures.
+
+   - nginx and lighttpd FCGI requests with URI encoded sections as the first
+     path part have been fixed to operate correctly.
+
+   - A source of bogus warnings in Catalyst::Component::BUILDARGS has been
+     removed.
+
+  Documentation:
+   - Improve the documentation about -Home and how Catalyst finds the home path
+     for applications.
+   - Various minor typo fixes.
+
+  New features:
+   - Allow passing additional arguments to action constructors.
+
 5.80018 2010-01-12 22:24:20
 
   Bug fixed:
    - Call ->canonical on URI derived from $ENV{REQUEST_URI} to get
      paths correctly decoded. This bug was previously hidden by a bug
-     in HTTP::Request::AsCGI
+     in HTTP::Request::AsCGI.
 
   Documentation:
    - Clarify that uri_for_action works on private paths, with example.
+   - Clarify documentation about debug
 
   Deprecations:
    - Saying use Catalyst::Test; (without an application name or () to stop
@@ -436,7 +562,7 @@
           B::Hooks::OP::Check::StashChange
         - Fix the unattached chain debug table for endpoints with no
           parents at all.
-        - Turn of test aggregation by default. Only aggregate if the
+        - Turn off test aggregation by default. Only aggregate if the
           AGGREGATE_TESTS environment variable is set and a recent
           Test::Aggregate is available.
         - Bump to MooseX::MethodAttributes 0.09, to gain the

Modified: Catalyst-Runtime/5.80/branches/psgi/Makefile.PL
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/Makefile.PL	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/Makefile.PL	2010-05-24 15:44:03 UTC (rev 13307)
@@ -1,14 +1,12 @@
 use strict;
 use warnings;
 use inc::Module::Install 0.91;
-{   # Ensure that these get used - yes, M::I loads them for us, but if you're
-    # in author mode and don't have them installed, then the error is tres
-    # cryptic.
-    no warnings 'redefine';
-    use Module::Install::AuthorRequires;
-    use Module::Install::CheckConflicts;
-    use Module::Install::AuthorTests;
-}
+# Ensure that these get used - yes, M::I loads them for us, but if you're
+# in author mode and don't have them installed, then the error is tres
+# cryptic.
+use Module::Install::AuthorRequires;
+use Module::Install::CheckConflicts;
+use Module::Install::AuthorTests;
 
 perl_version '5.008004';
 
@@ -17,20 +15,21 @@
 
 requires 'List::MoreUtils';
 requires 'namespace::autoclean' => '0.09';
-requires 'namespace::clean' => '0.12';
+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 'Data::OptList';
-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';
+requires 'CGI::Simple::Cookie' => '1.109';
 requires 'Data::Dump';
+requires 'Data::OptList';
 requires 'HTML::Entities';
-requires 'HTTP::Body'    => '1.04'; # makes uploadtmp work
+requires 'HTTP::Body'    => '1.06'; # ->cleanup(1)
 requires 'HTTP::Headers' => '1.64';
 requires 'HTTP::Request' => '5.814';
 requires 'HTTP::Response' => '5.813';
@@ -107,7 +106,8 @@
     you also install the development tools package Catalyst::Devel.
 
         perl -MCPANPLUS -e 'install Catalyst::Devel' # or
-        perl -MCPAN -e 'install Catalyst::Devel'
+        perl -MCPAN -e 'install Catalyst::Devel'     # or
+        cpanm Catalyst::Devel
 
     To get some commonly used plugins, as well as the TT view and DBIC
     model, install Task::Catalyst in the same way.

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Component.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Component.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Component.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -5,6 +5,7 @@
 use Class::MOP::Object;
 use Catalyst::Utils;
 use Class::C3::Adopt::NEXT;
+use Devel::InnerPackage ();
 use MRO::Compat;
 use mro 'c3';
 use Scalar::Util 'blessed';
@@ -84,8 +85,6 @@
         } elsif (Class::MOP::is_class_loaded($_[0]) &&
                 $_[0]->isa('Catalyst') && ref($_[1]) eq 'HASH') {
             $args = $_[1];
-        } elsif ($_[0] == $_[1]) {
-            $args = $_[1];
         } else {
             $args = +{ @_ };
         }
@@ -149,6 +148,11 @@
           . " did not override Catalyst::Component::process" );
 }
 
+sub expand_modules {
+    my ($class, $component) = @_;
+    return Devel::InnerPackage::list_packages( $component );
+}
+
 __PACKAGE__->meta->make_immutable;
 
 1;
@@ -157,7 +161,7 @@
 
 =head1 METHODS
 
-=head2 new($c, $arguments)
+=head2 new($app, $arguments)
 
 Called by COMPONENT to instantiate the component; should return an object
 to be stored in the application's component hash.
@@ -168,9 +172,10 @@
 
 If this method is present (as it is on all Catalyst::Component subclasses,
 it is called by Catalyst during setup_components with the application class
-as $c and any config entry on the application for this component (for example,
+as $app and any config entry on the application for this component (for example,
 in the case of MyApp::Controller::Foo this would be
 C<< MyApp->config('Controller::Foo' => \%conf >>).
+
 The arguments are expected to be a hashref and are merged with the
 C<< __PACKAGE__->config >> hashref before calling C<< ->new >>
 to instantiate the component.
@@ -206,6 +211,13 @@
 Merges two hashes together recursively, giving right-hand precedence.
 Alias for the method in L<Catalyst::Utils>.
 
+=head2 $c->expand_modules( $setup_component_config )
+
+Return a list of extra components that this component has created. By default,
+it just looks for a list of inner packages of this component
+
+=cut
+
 =head1 OPTIONAL METHODS
 
 =head2 ACCEPT_CONTEXT($c, @args)

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Controller.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Controller.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Controller.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -255,9 +255,15 @@
     my $class = (exists $args{attributes}{ActionClass}
                     ? $args{attributes}{ActionClass}[0]
                     : $self->_action_class);
+    Class::MOP::load_class($class);
 
-    Class::MOP::load_class($class);
-    return $class->new( \%args );
+    my $action_args = $self->config->{action_args};
+    my %extra_args = (
+        %{ $action_args->{'*'}           || {} },
+        %{ $action_args->{ $args{name} } || {} },
+    );
+
+    return $class->new({ %extra_args, %args });
 }
 
 sub _parse_attrs {
@@ -440,6 +446,46 @@
 
 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 and specifically (as above).
+This is particularly useful when using C<ActionRole>s
+(L<Catalyst::Controller::ActionRole>) and custom C<ActionClass>es.
+
+    __PACKAGE__->config(
+        action_args => {
+            '*' => { globalarg1 => 'hello', globalarg2 => 'goodbye' },
+            'specific_action' => { customarg => 'arg1' },
+        },
+     );
+
+In the case above the action class associated with C<specific_action> would get
+passed the following arguments, in addition to the normal action constructor
+arguments, when it is instantiated:
+
+  (globalarg1 => 'hello', globalarg2 => 'goodbye', customarg => 'arg1')
+
 =head1 METHODS
 
 =head2 BUILDARGS ($app, @args)

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Chained.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Chained.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Chained.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -105,7 +105,7 @@
             if (my $cap = $curr->attributes->{CaptureArgs}) {
                 unshift(@parts, (("*") x $cap->[0]));
             }
-            if (my $pp = $curr->attributes->{PartPath}) {
+            if (my $pp = $curr->attributes->{PathPart}) {
                 unshift(@parts, $pp->[0])
                     if (defined $pp->[0] && length $pp->[0]);
             }
@@ -304,7 +304,7 @@
         );
     }
 
-    $action->attributes->{PartPath} = [ $part ];
+    $action->attributes->{PathPart} = [ $part ];
 
     unshift(@{ $children->{$part} ||= [] }, $action);
 
@@ -358,7 +358,7 @@
                 unshift(@parts, splice(@captures, -$cap->[0]));
             }
         }
-        if (my $pp = $curr->attributes->{PartPath}) {
+        if (my $pp = $curr->attributes->{PathPart}) {
             unshift(@parts, $pp->[0])
                 if (defined($pp->[0]) && length($pp->[0]));
         }

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Index.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Index.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Index.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -67,7 +67,7 @@
 sub register {
     my ( $self, $c, $action ) = @_;
 
-    $self->_actions->{ $action->reverse } = $action;
+    $self->_actions->{ $action->reverse } = $action if $action->name eq 'index';
 
     return 1;
 }
@@ -84,7 +84,7 @@
 
     return undef if @$captures;
 
-    return undef unless $action->name eq 'index';
+    return undef unless exists $self->_actions->{ $action->reverse };
 
     return "/".$action->namespace;
 }

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Regex.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Regex.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/DispatchType/Regex.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -151,6 +151,7 @@
             my $re = "$orig";
             $re =~ s/^\^//;
             $re =~ s/\$$//;
+            $re =~ s/\\([^\\])/$1/g;
             my $final = '/';
             my @captures = @$captures;
             while (my ($front, $rest) = split(/\(/, $re, 2)) {

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Engine.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Engine.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Engine.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -345,6 +345,8 @@
 sub finalize_uploads {
     my ( $self, $c ) = @_;
 
+    # N.B. This code is theoretically entirely unneeded due to ->cleanup(1)
+    #      on the HTTP::Body object.
     my $request = $c->request;
     foreach my $key (keys %{ $request->uploads }) {
         my $upload = $request->uploads->{$key};
@@ -369,6 +371,7 @@
         unless ( $request->_body ) {
             my $type = $request->header('Content-Type');
             $request->_body(HTTP::Body->new( $type, $length ));
+            $request->_body->cleanup(1); # Make extra sure!
             $request->_body->tmpdir( $appclass->config->{uploadtmp} )
               if exists $appclass->config->{uploadtmp};
         }
@@ -651,7 +654,7 @@
             my $u = Catalyst::Request::Upload->new
               (
                size => $upload->{size},
-               type => $headers->content_type,
+               type => scalar $headers->content_type,
                headers => $headers,
                tempname => $upload->{tempname},
                filename => $upload->{filename},
@@ -838,13 +841,13 @@
 
 =head2 $self->env
 
-Hash containing enviroment variables including many special variables inserted
+Hash containing environment variables including many special variables inserted
 by WWW server - like SERVER_*, REMOTE_*, HTTP_* ...
 
-Before accesing enviroment variables consider whether the same information is
+Before accessing environment variables consider whether the same information is
 not directly available via Catalyst objects $c->request, $c->engine ...
 
-BEWARE: If you really need to access some enviroment variable from your Catalyst
+BEWARE: If you really need to access some environment variable from your Catalyst
 application you should use $c->engine->env->{VARNAME} instead of $ENV{VARNAME},
 as in some enviroments the %ENV hash does not contain what you would expect.
 

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Runtime.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Runtime.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Runtime.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -7,10 +7,8 @@
 
 # Remember to update this in Catalyst as well!
 
-our $VERSION='5.80018';
+our $VERSION = '5.80024';
 
-$VERSION = eval $VERSION;
-
 =head1 NAME
 
 Catalyst::Runtime - The Catalyst Framework Runtime

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Script/Create.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Script/Create.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Script/Create.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -46,7 +46,7 @@
     Class::MOP::load_class($helper_class);
     my $helper = $helper_class->new( { '.newfiles' => !$self->force, mech => $self->mechanize } );
 
-    $self->_getopt_full_usage unless $helper->mk_component( $self->application_name, @ARGV );
+    $self->_getopt_full_usage unless $helper->mk_component( $self->application_name, @{$self->extra_argv} );
 
 }
 
@@ -68,7 +68,7 @@
  Examples:
    myapp_create.pl controller My::Controller
    myapp_create.pl controller My::Controller BindLex
-   myapp_create.pl -mechanize controller My::Controller
+   myapp_create.pl --mechanize controller My::Controller
    myapp_create.pl view My::View
    myapp_create.pl view MyView TT
    myapp_create.pl view TT TT

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Script/Test.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Script/Test.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Script/Test.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -10,7 +10,9 @@
 
     Catalyst::Test->import($self->application_name);
 
-    print request($self->ARGV->[0])->content  . "\n";
+    foreach my $arg (@{ $self->ARGV }) {
+        print request($arg)->content  . "\n";
+    }
 }
 
 

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/ScriptRole.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/ScriptRole.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/ScriptRole.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -1,9 +1,9 @@
 package Catalyst::ScriptRole;
 use Moose::Role;
-use Plack::Runner;
 use MooseX::Types::Moose qw/Str Bool/;
 use Pod::Usage;
 use MooseX::Getopt;
+use Plack::Loader;
 use namespace::autoclean;
 
 with 'MooseX::Getopt' => {

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Test.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Test.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Test.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -206,6 +206,9 @@
     is ( $uri->path , '/y');
     my $content = get($uri->path);
 
+Note also that the content is returned as raw bytes, without any attempt
+to decode it into characters.
+
 =head2 $res = request( ... );
 
 Returns an L<HTTP::Response> object. Accepts an optional hashref for request

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Upgrading.pod
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Upgrading.pod	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst/Upgrading.pod	2010-05-24 15:44:03 UTC (rev 13307)
@@ -217,7 +217,7 @@
 
 Using this now causes infinite recursion between MyApp::setup and
 Catalyst::setup, due to other backwards compatibility issues related to how
-plugin setup works. Moose method modifiers like C<< before|after|around 'setup
+plugin setup works. Moose method modifiers like C<< before|after|around setup
 => sub { ... }; >> also will not operate correctly on the setup method.
 
 The right way to do it is this:

Modified: Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/lib/Catalyst.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -14,6 +14,7 @@
 use Catalyst::Response;
 use Catalyst::Utils;
 use Catalyst::Controller;
+use Data::OptList;
 use Devel::InnerPackage ();
 use File::stat;
 use Module::Pluggable::Object ();
@@ -79,8 +80,7 @@
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.80018';
-$VERSION = eval $VERSION;
+our $VERSION = '5.80024';
 
 sub import {
     my ( $class, @arguments ) = @_;
@@ -244,6 +244,9 @@
 settings override the application, with <MYAPP>_DEBUG having the highest
 priority.
 
+This sets the log level to 'debug' and enables full debug output on the
+error screen. If you only want the latter, see L<< $c->debug >>.
+
 =head2 -Engine
 
 Forces Catalyst to use a specific engine. Omit the
@@ -263,6 +266,14 @@
 the name will be replaced with underscores, e.g. MyApp::Web should use
 MYAPP_WEB_HOME. If both variables are set, the MYAPP_HOME one will be used.
 
+If none of these are set, Catalyst will attempt to automatically detect the
+home directory. If you are working in a development envirnoment, Catalyst
+will try and find the directory containing either Makefile.PL, Build.PL or
+dist.ini. If the application has been installed into the system (i.e.
+you have done C<make install>), then Catalyst will use the path to your
+application module, without the .pm extension (ie, /foo/MyApp if your
+application was installed at /foo/MyApp.pm)
+
 =head2 -Log
 
     use Catalyst '-Log=warn,fatal,error';
@@ -271,15 +282,16 @@
 
 =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
 
 =head2 INFORMATION ABOUT THE CURRENT REQUEST
@@ -332,7 +344,7 @@
 need to do something like:
 
     $c->forward('foo');
-    die $c->error if $c->error;
+    die join "\n", @{ $c->error } if @{ $c->error };
 
 Or make sure to always return true values from your actions and write
 your code like this:
@@ -628,7 +640,13 @@
 sub controller {
     my ( $c, $name, @args ) = @_;
 
+    my $appclass = ref($c) || $c;
     if( $name ) {
+        unless ( ref($name) ) { # Direct component hash lookup to avoid costly regexps
+            my $comps = $c->components;
+            my $check = $appclass."::Controller::".$name;
+            return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check};
+        }
         my @result = $c->_comp_search_prefixes( $name, qw/Controller C/ );
         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
         return $c->_filter_component( $result[ 0 ], @args );
@@ -662,6 +680,11 @@
     my ( $c, $name, @args ) = @_;
     my $appclass = ref($c) || $c;
     if( $name ) {
+        unless ( ref($name) ) { # Direct component hash lookup to avoid costly regexps
+            my $comps = $c->components;
+            my $check = $appclass."::Model::".$name;
+            return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check};
+        }
         my @result = $c->_comp_search_prefixes( $name, qw/Model M/ );
         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
         return $c->_filter_component( $result[ 0 ], @args );
@@ -716,6 +739,11 @@
 
     my $appclass = ref($c) || $c;
     if( $name ) {
+        unless ( ref($name) ) { # Direct component hash lookup to avoid costly regexps
+            my $comps = $c->components;
+            my $check = $appclass."::View::".$name;
+            return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check};
+        }
         my @result = $c->_comp_search_prefixes( $name, qw/View V/ );
         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
         return $c->_filter_component( $result[ 0 ], @args );
@@ -924,6 +952,8 @@
 
 =back
 
+The first three also set the log level to 'debug'.
+
 Calling C<< $c->debug(1) >> has no effect.
 
 =cut
@@ -1170,24 +1200,21 @@
     return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
 }
 
-
 =head2 $app->setup_finalize
 
-A hook to attach modifiers to.
-Using C<< after setup => sub{}; >> doesn't work, because of quirky things done for plugin setup.
-Also better than C< setup_finished(); >, as that is a getter method.
+A hook to attach modifiers to. This method does not do anything except set the
+C<setup_finished> accessor.
 
-    sub setup_finalize {
+Applying method modifiers to the C<setup> method doesn't work, because of quirky thingsdone for plugin setup.
 
+Example:
+
+    after setup_finalize => sub {
         my $app = shift;
 
-        ## do stuff, i.e., determine a primary key column for sessions stored in a DB
+        ## do stuff here..
+    };
 
-        $app->next::method(@_);
-
-
-    }
-
 =cut
 
 sub setup_finalize {
@@ -1247,11 +1274,29 @@
         $path .= '/';
     }
 
+    undef($path) if (defined $path && $path eq '');
+
+    my $params =
+      ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
+
+    carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
+    foreach my $arg (@args) {
+        utf8::encode($arg) if utf8::is_utf8($arg);
+        $arg =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
+    }
+
     if ( blessed($path) ) { # action object
-        my $captures = [ map { s|/|%2F|; $_; }
+        s|/|%2F|g for @args;
+        my $captures = [ map { s|/|%2F|g; $_; }
                         ( scalar @args && ref $args[0] eq 'ARRAY'
                          ? @{ shift(@args) }
                          : ()) ];
+
+        foreach my $capture (@$captures) {
+            utf8::encode($capture) if utf8::is_utf8($capture);
+            $capture =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go;
+        }
+
         my $action = $path;
         $path = $c->dispatcher->uri_for_action($action, $captures);
         if (not defined $path) {
@@ -1262,15 +1307,6 @@
         $path = '/' if $path eq '';
     }
 
-    undef($path) if (defined $path && $path eq '');
-
-    my $params =
-      ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
-
-    carp "uri_for called with undef argument" if grep { ! defined $_ } @args;
-    s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
-    s|/|%2F| for @args;
-
     unshift(@args, $path);
 
     unless (defined $path && $path =~ s!^/!!) { # in-place strip
@@ -1476,7 +1512,7 @@
                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AModel%3A%3A&amp;mode=all">models</a>, and
                     <a href="http://cpansearch.perl.org/search?query=Catalyst%3A%3AView%3A%3A&amp;mode=all">views</a>;
                     they can save you a lot of work.</p>
-                    <pre><code>script/${prefix}_create.pl -help</code></pre>
+                    <pre><code>script/${prefix}_create.pl --help</code></pre>
                     <p>Also, be sure to check out the vast and growing
                     collection of <a href="http://search.cpan.org/search?query=Catalyst">plugins for Catalyst on CPAN</a>;
                     you are likely to find what you need there.
@@ -1719,6 +1755,8 @@
         $c->finalize_body;
     }
 
+    $c->log_response;
+
     if ($c->use_stats) {
         my $elapsed = sprintf '%f', $c->stats->elapsed;
         my $av = $elapsed == 0 ? '??' : sprintf '%.3f', 1 / $elapsed;
@@ -1851,7 +1889,7 @@
 
 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.
 
@@ -1910,7 +1948,7 @@
 
     #surely this is not the most efficient way to do things...
     $c->stats($class->stats_class->new)->enable($c->use_stats);
-    if ( $c->debug ) {
+    if ( $c->debug || $c->config->{enable_catalyst_header} ) {
         $c->res->headers->header( 'X-Catalyst' => $Catalyst::VERSION );
     }
 
@@ -1952,8 +1990,7 @@
     $path       = '/' unless length $path;
     my $address = $c->req->address || '';
 
-    $c->log->debug(qq/"$method" request for "$path" from "$address"/)
-      if $c->debug;
+    $c->log_request;
 
     $c->prepare_action;
 
@@ -1983,17 +2020,6 @@
     $c->engine->prepare_body( $c, @_ );
     $c->prepare_parameters;
     $c->prepare_uploads;
-
-    if ( $c->debug && keys %{ $c->req->body_parameters } ) {
-        my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
-        for my $key ( sort keys %{ $c->req->body_parameters } ) {
-            my $param = $c->req->body_parameters->{$key};
-            my $value = defined($param) ? $param : '';
-            $t->row( $key,
-                ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
-        }
-        $c->log->debug( "Body Parameters are:\n" . $t->draw );
-    }
 }
 
 =head2 $c->prepare_body_chunk( $chunk )
@@ -2077,55 +2103,156 @@
     my $c = shift;
 
     $c->engine->prepare_query_parameters( $c, @_ );
+}
 
-    if ( $c->debug && keys %{ $c->request->query_parameters } ) {
-        my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ 36, 'Value' ] );
-        for my $key ( sort keys %{ $c->req->query_parameters } ) {
-            my $param = $c->req->query_parameters->{$key};
-            my $value = defined($param) ? $param : '';
-            $t->row( $key,
-                ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
-        }
-        $c->log->debug( "Query Parameters are:\n" . $t->draw );
+=head2 $c->log_request
+
+Writes information about the request to the debug logs.  This includes:
+
+=over 4
+
+=item * Request method, path, and remote IP address
+
+=item * Query keywords (see L<Catalyst::Request/query_keywords>)
+
+=item * Request parameters
+
+=item * File uploads
+
+=back
+
+=cut
+
+sub log_request {
+    my $c = shift;
+
+    return unless $c->debug;
+
+    my($dump) = grep {$_->[0] eq 'Request' } $c->dump_these;
+    my $request = $dump->[1];
+
+    my ( $method, $path, $address ) = ( $request->method, $request->path, $request->address );
+    $method ||= '';
+    $path = '/' unless length $path;
+    $address ||= '';
+    $c->log->debug(qq/"$method" request for "$path" from "$address"/);
+
+    $c->log_request_headers($request->headers);
+
+    if ( my $keywords = $request->query_keywords ) {
+        $c->log->debug("Query keywords are: $keywords");
     }
+
+    $c->log_request_parameters( query => $request->query_parameters, body => $request->body_parameters );
+
+    $c->log_request_uploads($request);
 }
 
-=head2 $c->prepare_read
+=head2 $c->log_response
 
-Prepares the input for reading.
+Writes information about the response to the debug logs by calling
+C<< $c->log_response_status_line >> and C<< $c->log_response_headers >>.
 
 =cut
 
-sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
+sub log_response {
+    my $c = shift;
 
-=head2 $c->prepare_request
+    return unless $c->debug;
 
-Prepares the engine request.
+    my($dump) = grep {$_->[0] eq 'Response' } $c->dump_these;
+    my $response = $dump->[1];
 
+    $c->log_response_status_line($response);
+    $c->log_response_headers($response->headers);
+}
+
+=head2 $c->log_response_status_line($response)
+
+Writes one line of information about the response to the debug logs.  This includes:
+
+=over 4
+
+=item * Response status code
+
+=item * Content-Type header (if present)
+
+=item * Content-Length header (if present)
+
+=back
+
 =cut
 
-sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
+sub log_response_status_line {
+    my ($c, $response) = @_;
 
-=head2 $c->prepare_uploads
+    $c->log->debug(
+        sprintf(
+            'Response Code: %s; Content-Type: %s; Content-Length: %s',
+            $response->status                            || 'unknown',
+            $response->headers->header('Content-Type')   || 'unknown',
+            $response->headers->header('Content-Length') || 'unknown'
+        )
+    );
+}
 
-Prepares uploads.
+=head2 $c->log_response_headers($headers);
 
+Hook method which can be wrapped by plugins to log the responseheaders.
+No-op in the default implementation.
+
 =cut
 
-sub prepare_uploads {
-    my $c = shift;
+sub log_response_headers {}
 
-    $c->engine->prepare_uploads( $c, @_ );
+=head2 $c->log_request_parameters( query => {}, body => {} )
 
-    if ( $c->debug && keys %{ $c->request->uploads } ) {
+Logs request parameters to debug logs
+
+=cut
+
+sub log_request_parameters {
+    my $c          = shift;
+    my %all_params = @_;
+
+    return unless $c->debug;
+
+    my $column_width = Catalyst::Utils::term_width() - 44;
+    foreach my $type (qw(query body)) {
+        my $params = $all_params{$type};
+        next if ! keys %$params;
+        my $t = Text::SimpleTable->new( [ 35, 'Parameter' ], [ $column_width, 'Value' ] );
+        for my $key ( sort keys %$params ) {
+            my $param = $params->{$key};
+            my $value = defined($param) ? $param : '';
+            $t->row( $key, ref $value eq 'ARRAY' ? ( join ', ', @$value ) : $value );
+        }
+        $c->log->debug( ucfirst($type) . " Parameters are:\n" . $t->draw );
+    }
+}
+
+=head2 $c->log_request_uploads
+
+Logs file uploads included in the request to the debug logs.
+The parameter name, filename, file type, and file size are all included in
+the debug logs.
+
+=cut
+
+sub log_request_uploads {
+    my $c = shift;
+    my $request = shift;
+    return unless $c->debug;
+    my $uploads = $request->uploads;
+    if ( keys %$uploads ) {
         my $t = Text::SimpleTable->new(
             [ 12, 'Parameter' ],
             [ 26, 'Filename' ],
             [ 18, 'Type' ],
             [ 9,  'Size' ]
         );
-        for my $key ( sort keys %{ $c->request->uploads } ) {
-            my $upload = $c->request->uploads->{$key};
+        for my $key ( sort keys %$uploads ) {
+            my $upload = $uploads->{$key};
             for my $u ( ref $upload eq 'ARRAY' ? @{$upload} : ($upload) ) {
                 $t->row( $key, $u->filename, $u->type, $u->size );
             }
@@ -2134,6 +2261,68 @@
     }
 }
 
+=head2 $c->log_request_headers($headers);
+
+Hook method which can be wrapped by plugins to log the request headers.
+No-op in the default implementation.
+
+=cut
+
+sub log_request_headers {}
+
+=head2 $c->log_headers($type => $headers)
+
+Logs L<HTTP::Headers> (either request or response) to the debug logs.
+
+=cut
+
+sub log_headers {
+    my $c       = shift;
+    my $type    = shift;
+    my $headers = shift;    # an HTTP::Headers instance
+
+    return unless $c->debug;
+
+    my $column_width = Catalyst::Utils::term_width() - 28;
+    my $t = Text::SimpleTable->new( [ 15, 'Header Name' ], [ $column_width, 'Value' ] );
+    $headers->scan(
+        sub {
+            my ( $name, $value ) = @_;
+            $t->row( $name, $value );
+        }
+    );
+    $c->log->debug( ucfirst($type) . " Headers:\n" . $t->draw );
+}
+
+
+=head2 $c->prepare_read
+
+Prepares the input for reading.
+
+=cut
+
+sub prepare_read { my $c = shift; $c->engine->prepare_read( $c, @_ ) }
+
+=head2 $c->prepare_request
+
+Prepares the engine request.
+
+=cut
+
+sub prepare_request { my $c = shift; $c->engine->prepare_request( $c, @_ ) }
+
+=head2 $c->prepare_uploads
+
+Prepares uploads.
+
+=cut
+
+sub prepare_uploads {
+    my $c = shift;
+
+    $c->engine->prepare_uploads( $c, @_ );
+}
+
 =head2 $c->prepare_write
 
 Prepares the output for writing.
@@ -2227,17 +2416,15 @@
         # we know M::P::O found a file on disk so this is safe
 
         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
-
-        # Needs to be done as soon as the component is loaded, as loading a sub-component
-        # (next time round the loop) can cause us to get the wrong metaclass..
-        $class->_controller_init_base_classes($component);
     }
 
     for my $component (@comps) {
-        $class->components->{ $component } = $class->setup_component($component);
-        for my $component ($class->expand_component_module( $component, $config )) {
+        my $instance = $class->components->{ $component } = $class->setup_component($component);
+        my @expanded_components = $instance->can('expand_modules')
+            ? $instance->expand_modules( $component, $config )
+            : $class->expand_component_module( $component, $config );
+        for my $component (@expanded_components) {
             next if $comps{$component};
-            $class->_controller_init_base_classes($component); # Also cover inner packages
             $class->components->{ $component } = $class->setup_component($component);
         }
     }
@@ -2290,19 +2477,6 @@
 
 =cut
 
-# FIXME - Ugly, ugly hack to ensure the we force initialize non-moose base classes
-#         nearest to Catalyst::Controller first, no matter what order stuff happens
-#         to be loaded. There are TODO tests in Moose for this, see
-#         f2391d17574eff81d911b97be15ea51080500003
-sub _controller_init_base_classes {
-    my ($app_class, $component) = @_;
-    return unless $component->isa('Catalyst::Controller');
-    foreach my $class ( reverse @{ mro::get_linear_isa($component) } ) {
-        Moose::Meta::Class->initialize( $class )
-            unless find_meta($class);
-    }
-}
-
 sub setup_component {
     my( $class, $component ) = @_;
 
@@ -2542,13 +2716,8 @@
             if $plugin->isa( 'Catalyst::Component' );
         $proto->_plugins->{$plugin} = 1;
         unless ($instant) {
-            no strict 'refs';
-            if ( my $meta = Class::MOP::get_metaclass_by_name($class) ) {
-              my @superclasses = ($plugin, $meta->superclasses );
-              $meta->superclasses(@superclasses);
-            } else {
-              unshift @{"$class\::ISA"}, $plugin;
-            }
+            my $meta = Class::MOP::get_metaclass_by_name($class);
+            $meta->superclasses($plugin, $meta->superclasses);
         }
         return $class;
     }
@@ -2557,22 +2726,29 @@
         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(
@@ -2586,15 +2762,24 @@
 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) >>.
@@ -2692,6 +2877,12 @@
 
 =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
@@ -2921,8 +3112,12 @@
 
 Robert Sedlacek C<< <rs at 474.at> >>
 
+SpiceMan: Marcel Montes
+
 sky: Arthur Bergman
 
+szbalint: Balint Szilakszi <szbalint at cpan.org>
+
 t0m: Tomas Doran <bobtfish at bobtfish.net>
 
 Ulf Edvinsson
@@ -2933,6 +3128,8 @@
 
 willert: Sebastian Willert <willert at cpan.org>
 
+wreis: Wallace Reis <wallace at reis.org.br>
+
 Yuval Kogman, C<nothingmuch at woobling.org>
 
 =head1 LICENSE

Modified: Catalyst-Runtime/5.80/branches/psgi/script/catalyst.pl
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/script/catalyst.pl	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/script/catalyst.pl	2010-05-24 15:44:03 UTC (rev 13307)
@@ -142,7 +142,7 @@
 
 =item C<myapp_test.pl>
 
-runs an action of the generated application from the comand line.
+runs an action of the generated application from the command line.
 
 =back
 

Added: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/catalyst_test_utf8.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/catalyst_test_utf8.t	                        (rev 0)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/catalyst_test_utf8.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -0,0 +1,27 @@
+use strict;
+use warnings;
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use Test::More;
+# "binmode STDOUT, ':utf8'" is insufficient, see http://code.google.com/p/test-more/issues/detail?id=46#c1
+binmode Test::More->builder->output, ":utf8";
+binmode Test::More->builder->failure_output, ":utf8";
+
+use Catalyst::Test 'TestAppEncoding';
+
+plan skip_all => 'This test does not run live'
+    if $ENV{CATALYST_SERVER};
+
+{   
+    # Test for https://rt.cpan.org/Ticket/Display.html?id=53678
+    # Catalyst::Test::get currently returns the raw octets, but it
+    # would be more useful if it decoded the content based on the
+    # Content-Type charset, as Test::WWW::Mechanize::Catalyst does
+    use utf8;
+    my $body = get('/utf8_non_ascii_content');
+    utf8::decode($body);
+    is $body, 'ʇsʎlɐʇɐɔ', 'Catalyst::Test::get returned content correctly UTF-8 encoded';
+}
+
+done_testing;

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_action_action.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_action_action.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_action_action.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -10,7 +10,7 @@
 
 BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
 
-use Test::More tests => 42 * $iters;
+use Test::More;
 use Catalyst::Test 'TestApp';
 
 if ( $ENV{CAT_BENCHMARK} ) {
@@ -147,4 +147,25 @@
         );
     }
 
+    {
+        ok( my $response = request('http://localhost/action_action_seven'),
+            '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_seven', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Action',
+            'Test Class'
+        );
+        is( $response->header('X-TestExtraArgsAction'), '42,23', 'Extra args get passed to action contstructor' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
 }
+
+done_testing;

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_action_chained.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_action_chained.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_action_chained.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -1074,6 +1074,7 @@
         ['foo%2Fbar', 'baz%2Fquux'],
         ['foo%2Fbar', 'baz%2Fquux', { foo => 'bar', 'baz' => 'quux%2Ffrood'}],
         ['foo%2Fbar', 'baz%2Fquux', { foo => 'bar', 'baz%2Ffnoo' => 'quux%2Ffrood'}],
+        ['h%C3%BCtte', 'h%C3%BCtte', { test => 'h%C3%BCtte' } ],
     ) {
         my $path = '/chained/roundtrip_urifor/' .
             $thing->[0] . '/' . $thing->[1];
@@ -1085,7 +1086,8 @@
             'request ' . $path . ' ok');
         # Just check that the path matches, as who the hell knows or cares
         # where the app is based (live tests etc)
-        ok( index($content, $path) > 1, 'uri can round trip through uri_for' );
+        ok( index($content, $path) > 1, 'uri can round trip through uri_for' )
+            or diag("Expected $path, got $content");
     }
 }
 

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_args.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_args.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/live_component_controller_args.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -73,15 +73,15 @@
 
         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;
 

Added: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_component_generating.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_component_generating.t	                        (rev 0)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_component_generating.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -0,0 +1,10 @@
+use Test::More tests => 3;
+use strict;
+use warnings;
+
+use lib 't/lib';
+use TestApp;
+
+ok(TestApp->model('Generating'), 'knows about generating model');
+ok(TestApp->model('Generated'), 'knows about the generated model');
+is(TestApp->model('Generated')->foo, 'foo', 'can operate on generated model');

Added: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_ctx_attr.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_ctx_attr.t	                        (rev 0)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_ctx_attr.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -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;
+

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_path_to.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_path_to.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_path_to.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -2,6 +2,9 @@
 use warnings;
 
 use Test::More;
+use FindBin;
+use Path::Class;
+use File::Basename;
 
 my %non_unix = (
     MacOS   => 1,
@@ -16,17 +19,20 @@
 
 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 @@
 
 is( Catalyst::path_to( $context, 'foo', 'bar' ),
     '/Users/sri/myapp/foo/bar', 'deep Unix path' );
+
+done_testing;

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_plugin.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_plugin.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_plugin.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 24;
+use Test::More;
 
 use lib 't/lib';
 
@@ -61,3 +61,4 @@
 is_deeply [ TestApp->registered_plugins ], \@expected,
   'registered_plugins() should only report the plugins for the current class';
 
+done_testing;

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_cgi.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_cgi.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_cgi.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -15,8 +15,8 @@
     Catalyst::Script::CGI->new_with_options(application_name => 'TestAppToTestScripts')->run;
 } "new_with_options";
 shift @TestAppToTestScripts::RUN_ARGS;
-my $server = shift @TestAppToTestScripts::RUN_ARGS;
-like ref($server), qr/^Plack::Server/, 'Is a Plack Server';
+my $server = pop @TestAppToTestScripts::RUN_ARGS;
+like ref($server), qr/^Plack::Handler/, 'Is a Plack::Handler';
 is_deeply \@TestAppToTestScripts::RUN_ARGS, [], "no args";
 
 done_testing;

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_fastcgi.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_fastcgi.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_fastcgi.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -51,8 +51,8 @@
     } "new_with_options";
     # First element of RUN_ARGS will be the script name, which we don't care about
     shift @TestAppToTestScripts::RUN_ARGS;
-    my $server = shift @TestAppToTestScripts::RUN_ARGS;
-    like ref($server), qr/^Plack::Server/, 'Is a Plack Server';
+    my $server = pop @TestAppToTestScripts::RUN_ARGS;
+    like ref($server), qr/^Plack::Handler/, 'Is a Plack::Handler';
     is_deeply \@TestAppToTestScripts::RUN_ARGS, $resultarray, "is_deeply comparison";
 }
 

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_server.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_server.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_server.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -89,8 +89,8 @@
     };
     # First element of RUN_ARGS will be the script name, which we don't care about
     shift @TestAppToTestScripts::RUN_ARGS;
-    my $server = shift @TestAppToTestScripts::RUN_ARGS;
-    like ref($server), qr/^Plack::Server/, 'Is a Plack Server';
+    my $server = pop @TestAppToTestScripts::RUN_ARGS;
+    like ref($server), qr/^Plack::Handler/, 'Is a Plack::Handler';
     # Mangle argv into the options..
     $resultarray->[-1]->{argv} = $argstring;
     is_deeply \@TestAppToTestScripts::RUN_ARGS, $resultarray, "is_deeply comparison " . join(' ', @$argstring);

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_test.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_test.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_script_test.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -1,6 +1,7 @@
 use strict;
 use warnings;
 
+use Carp qw(croak);
 use FindBin qw/$Bin/;
 use lib "$Bin/../lib";
 

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -1,16 +1,17 @@
 use strict;
 use warnings;
-
-use Test::More tests => 20;
+use FindBin qw/$Bin/;
+use lib "$FindBin::Bin/../lib";
+use Test::More;
 use URI;
 
-use_ok('Catalyst');
+use_ok('TestApp');
 
 my $request = Catalyst::Request->new( {
                 base => URI->new('http://127.0.0.1/foo')
               } );
-
-my $context = Catalyst->new( {
+my $dispatcher = TestApp->dispatcher;
+my $context = TestApp->new( {
                 request => $request,
                 namespace => 'yada',
               } );
@@ -143,3 +144,32 @@
     is_deeply($query_params_base, $query_params_test,
               "uri_for() doesn't mess up query parameter hash in the caller");
 }
+
+
+{
+    my $path_action = $dispatcher->get_action_by_path(
+                       '/action/path/six'
+                     );
+
+    # 5.80018 is only encoding the first of the / in the arg.
+    is(
+        Catalyst::uri_for( $context, $path_action, 'foo/bar/baz' )->as_string,
+        'http://127.0.0.1/action/path/six/foo%2Fbar%2Fbaz',
+        'Escape all forward slashes in args as %2F'
+    );
+}
+
+{
+    my $index_not_private = $dispatcher->get_action_by_path(
+                             '/action/chained/argsorder/index'
+                            );
+
+    is(
+      Catalyst::uri_for( $context, $index_not_private )->as_string,
+      'http://127.0.0.1/argsorder',
+      'Return non-DispatchType::Index path for index action with args'
+    );
+}
+
+done_testing;
+

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for_action.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for_action.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for_action.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -8,7 +8,7 @@
 
 use Test::More;
 
-plan tests => 30;
+plan tests => 33;
 
 use_ok('TestApp');
 
@@ -54,6 +54,21 @@
    "/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
 #

Modified: Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for_multibytechar.t
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for_multibytechar.t	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/aggregate/unit_core_uri_for_multibytechar.t	2010-05-24 15:44:03 UTC (rev 13307)
@@ -1,10 +1,9 @@
 use strict;
 use warnings;
-
 use FindBin;
 use lib "$FindBin::Bin/../lib";
 
-use Test::More tests => 5;
+use Test::More;
 
 use_ok('TestApp');
 
@@ -33,3 +32,19 @@
 # multibyte with utf8 string
 is($context->uri_for('/', { name => "\x{6751}\x{702c}\x{5927}\x{8f14}" }), $uri_with_multibyte, 'uri_for with utf8 string query');
 is($context->req->uri_with({ name => "\x{6751}\x{702c}\x{5927}\x{8f14}" }), $uri_with_multibyte, 'uri_with with utf8 string query');
+
+# multibyte captures and args
+my $action = $context->controller('Action::Chained')
+    ->action_for('roundtrip_urifor_end');
+
+{
+use utf8;
+
+is($context->uri_for($action, ['hütte'], 'hütte', {
+    test => 'hütte'
+}),
+'http://127.0.0.1/chained/roundtrip_urifor/h%C3%BCtte/h%C3%BCtte?test=h%C3%BCtte',
+'uri_for with utf8 captures and args');
+}
+
+done_testing;

Modified: Catalyst-Runtime/5.80/branches/psgi/t/lib/PluginTestApp/Controller/Root.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/lib/PluginTestApp/Controller/Root.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/lib/PluginTestApp/Controller/Root.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -34,6 +34,13 @@
     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';

Modified: Catalyst-Runtime/5.80/branches/psgi/t/lib/PluginTestApp.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/lib/PluginTestApp.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/lib/PluginTestApp.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -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;

Added: Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Action/TestExtraArgsAction.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Action/TestExtraArgsAction.pm	                        (rev 0)
+++ Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Action/TestExtraArgsAction.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -0,0 +1,17 @@
+package TestApp::Action::TestExtraArgsAction;
+
+use Moose;
+use namespace::autoclean;
+
+extends 'Catalyst::Action';
+
+has [qw/extra_arg another_extra_arg/] => (is => 'ro');
+
+after execute => sub {
+    my ($self, $controller, $ctx) = @_;
+    $ctx->response->header('X-TestExtraArgsAction' => join q{,} => $self->extra_arg, $self->another_extra_arg);
+};
+
+__PACKAGE__->meta->make_immutable;
+
+1;

Modified: Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Controller/Action/Action.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Controller/Action/Action.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Controller/Action/Action.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -3,7 +3,15 @@
 use strict;
 use base 'TestApp::Controller::Action';
 
-__PACKAGE__->config( actions => { action_action_five => { ActionClass => '+Catalyst::Action::TestBefore' } } );
+__PACKAGE__->config(
+    actions => {
+        action_action_five => { ActionClass => '+Catalyst::Action::TestBefore' },
+    },
+    action_args => {
+        '*'                 => { extra_arg         => 42 },
+        action_action_seven => { another_extra_arg => 23 },
+    },
+);
 
 sub action_action_one : Global : ActionClass('TestBefore') {
     my ( $self, $c ) = @_;
@@ -38,4 +46,9 @@
     $c->forward('TestApp::View::Dump::Request');
 }
 
+sub action_action_seven : Global : ActionClass('~TestExtraArgsAction') {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
 1;

Modified: Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Controller/Action/Regexp.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Controller/Action/Regexp.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Controller/Action/Regexp.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -27,4 +27,9 @@
     );
 }
 
+sub one_backslashes : Action Regex('^action/regexp/(\w+)/(\d+)\.html$') {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
 1;

Added: Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Model/Generating.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Model/Generating.pm	                        (rev 0)
+++ Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Model/Generating.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -0,0 +1,22 @@
+package TestApp::Model::Generating;
+use Moose;
+extends 'Catalyst::Model';
+
+sub BUILD {
+    Class::MOP::Class->create(
+        'TestApp::Model::Generated' => (
+            methods => {
+                foo => sub { 'foo' }
+            }
+        )
+    );
+}
+
+sub expand_modules {
+    return ('TestApp::Model::Generated');
+}
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;

Added: Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Plugin/ParameterizedRole.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Plugin/ParameterizedRole.pm	                        (rev 0)
+++ Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp/Plugin/ParameterizedRole.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -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;

Modified: Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/lib/TestApp.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -16,10 +16,39 @@
 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
+# above ->setup so we have some generated methods to be double sure.
+has an_attribute_before_we_change_base_classes => ( is => 'ro');
+
 if ($::setup_leakchecker && eval { Class::MOP::load_class('CatalystX::LeakChecker'); 1 }) {
     with 'CatalystX::LeakChecker';
 

Modified: Catalyst-Runtime/5.80/branches/psgi/t/lib/TestAppEncoding/Controller/Root.pm
===================================================================
--- Catalyst-Runtime/5.80/branches/psgi/t/lib/TestAppEncoding/Controller/Root.pm	2010-05-24 09:58:27 UTC (rev 13306)
+++ Catalyst-Runtime/5.80/branches/psgi/t/lib/TestAppEncoding/Controller/Root.pm	2010-05-24 15:44:03 UTC (rev 13307)
@@ -8,7 +8,11 @@
 
 sub binary : Local {
     my ($self, $c) = @_;
-    $c->res->body(do { open(my $fh, '<', $c->path_to('..', '..', 'catalyst_130pix.gif')) or die $!; binmode($fh); local $/ = undef; <$fh>; });
+    $c->res->body(do { 
+        open(my $fh, '<', $c->path_to('..', '..', 'catalyst_130pix.gif')) or die $!; 
+        binmode($fh); 
+        local $/ = undef; <$fh>;
+    });
 }
 
 sub binary_utf8 : Local {
@@ -20,6 +24,23 @@
     $c->res->body($str);
 }
 
+# called by t/aggregate/catalyst_test_utf8.t
+sub utf8_non_ascii_content : Local {
+    use utf8;
+    my ($self, $c) = @_;
+    
+    my $str = 'ʇsʎlɐʇɐɔ';  # 'catalyst' flipped at http://www.revfad.com/flip.html
+    ok utf8::is_utf8($str), '$str is in UTF8 internally';
+    
+    # encode $str into a sequence of octets and turn off the UTF-8 flag, so that
+    # we don't get the 'Wide character in syswrite' error in Catalyst::Engine
+    utf8::encode($str);
+    ok !utf8::is_utf8($str), '$str is a sequence of octets (byte string)';
+    
+    $c->res->body($str);
+}
+
+
 sub end : Private {
     my ($self,$c) = @_;
 }




More information about the Catalyst-commits mailing list