Merge 'trunk' into 'uri_for_utf8'
Tomas Doran [Mon, 8 Feb 2010 20:58:18 +0000 (20:58 +0000)]
r12570@t0mlaptop (orig r12535):  rafl | 2010-01-06 15:59:41 +0000
Clarify comment.
r12589@t0mlaptop (orig r12554):  t0m | 2010-01-09 15:37:00 +0000
Don't screw over people using --detach, <sigh>
r12590@t0mlaptop (orig r12555):  t0m | 2010-01-09 15:57:27 +0000
Back out r12493, use \Q instead
r12591@t0mlaptop (orig r12556):  t0m | 2010-01-09 15:58:18 +0000
Changelog Adopt::NEXT warnings
r12592@t0mlaptop (orig r12557):  t0m | 2010-01-09 16:43:25 +0000
Correctly pass argv option into Catalyst::Engine::HTTP
r12593@t0mlaptop (orig r12558):  t0m | 2010-01-09 16:54:08 +0000
Un stupid
r12594@t0mlaptop (orig r12559):  t0m | 2010-01-09 17:38:59 +0000
Bump dep
r12608@t0mlaptop (orig r12573):  t0m | 2010-01-09 18:22:02 +0000
Bump version of ::Role::WithOverloading
r12610@t0mlaptop (orig r12575):  t0m | 2010-01-09 19:01:59 +0000
require autoclean once only
r12622@t0mlaptop (orig r12587):  rafl | 2010-01-10 02:00:03 +0000
Version 5.80017.
r12631@t0mlaptop (orig r12596):  t0m | 2010-01-10 14:22:15 +0000
Apply patch to clarify uri_for action from Octavian Rasnita on list
r12640@t0mlaptop (orig r12605):  t0m | 2010-01-11 21:11:05 +0000
Deprecate bare imports of Catalyst::Test - either use an app name or don't run the import method. As-per r12564
r12648@t0mlaptop (orig r12613):  t0m | 2010-01-11 23:18:08 +0000
Fix URI bug masked by HTTP::Request::AsCGI
r12652@t0mlaptop (orig r12617):  rafl | 2010-01-12 21:37:31 +0000
Fix a deprecation warning in the tests.
r12653@t0mlaptop (orig r12618):  rafl | 2010-01-12 21:37:39 +0000
canonical() is a no-op for the base uri.
r12654@t0mlaptop (orig r12619):  rafl | 2010-01-12 21:37:46 +0000
Version 5.80018.
r12669@t0mlaptop (orig r12634):  rafl | 2010-01-14 02:26:03 +0000
Depend on n:c 0.12 to work on perl >= 5.11.2.
r12673@t0mlaptop (orig r12638):  rafl | 2010-01-14 05:21:24 +0000
Exception stuff is fixed for a while now.
r12674@t0mlaptop (orig r12639):  rafl | 2010-01-14 05:45:09 +0000
Only set up the leakchecker for the tests that need it.

That way we avoid the useless Devel::Cycle glob warnings.
r12676@t0mlaptop (orig r12641):  dandv | 2010-01-14 08:15:10 +0000
Typo fix
r12678@t0mlaptop (orig r12643):  dandv | 2010-01-14 09:23:50 +0000
Cosmetic: wrapped long code line
r12690@t0mlaptop (orig r12655):  dandv | 2010-01-14 23:52:44 +0000
Passing test case for RT #53678 - Catalyst::Test::get currently doesn't decode the response body octets

r12691@t0mlaptop (orig r12656):  karpet | 2010-01-15 06:35:30 +0000
in what case is a numeric comparison called for? I cannot think of one. Is this the best way to test?
r12698@t0mlaptop (orig r12663):  t0m | 2010-01-15 16:39:55 +0000
Clarify that it's an app, not a ctx here
r12713@t0mlaptop (orig r12678):  rafl | 2010-01-18 09:00:20 +0000
Depend on a namespace::clean that isn't broken on <= 5.8.8.
r12725@t0mlaptop (orig r12690):  rafl | 2010-01-19 16:07:45 +0000
Merge branch 'action_args'

* action_args:
  And another minor tweak.
  Some more doc tweaking.
  tweaked docs based on IRC suggestions
  added documentation for the configuration option "action_args".
  Allow passing extra args to action constructors using action_args config.
  Add tests for passing extra arguments to action constructors.
  Create branch action_args
r12726@t0mlaptop (orig r12691):  rafl | 2010-01-19 16:08:22 +0000
Changelog action_args.
r12728@t0mlaptop (orig r12693):  aristotle | 2010-01-19 21:41:23 +0000
fix $c->error doc in Catalyst.pm POD
r12761@t0mlaptop (orig r12726):  aCiD2 | 2010-01-25 01:03:52 +0000
Improve the documentation about -Home and how Catalyst finds the home path for apps
r12762@t0mlaptop (orig r12727):  rafl | 2010-01-25 18:59:52 +0000
Revert "in what case is a numeric comparison called for? I cannot think of one. Is this the best way to test?"

This reverts commit 279b2f1abb0a8e056b8c905e5a4ecb66537ee194.
r12763@t0mlaptop (orig r12728):  rafl | 2010-01-25 19:00:17 +0000
Remove apparently useless Component::BUILDARGS conditional.
r12778@t0mlaptop (orig r12743):  t0m | 2010-01-27 20:12:46 +0000
Clarrify debug documentation
r12779@t0mlaptop (orig r12744):  t0m | 2010-01-27 20:15:52 +0000
Fix failing test related to missing g in regex
r12781@t0mlaptop (orig r12746):  t0m | 2010-01-27 21:04:17 +0000
Fix / => %2F in uri_for so that it only works for action objects as previously advertised as this has been screwing people. Also fix multiple / => %2F conversion in the same arg/capture
r12793@t0mlaptop (orig r12758):  t0m | 2010-01-28 15:47:31 +0000
Fix paths with URI encoding as the first path part
r12794@t0mlaptop (orig r12759):  t0m | 2010-01-28 18:15:10 +0000
And test the non root app case
r12804@t0mlaptop (orig r12769):  t0m | 2010-01-28 23:28:15 +0000
Changelog up to date
r12805@t0mlaptop (orig r12770):  rafl | 2010-01-29 00:16:42 +0000
Changelog tweaking.
r12806@t0mlaptop (orig r12771):  rafl | 2010-01-29 00:16:48 +0000
Version 5.80019.
r12845@t0mlaptop (orig r12810):  rafl | 2010-02-04 05:50:05 +0000
Merge branch 'expand_modules'

* expand_modules:
  Allow models and components to specify the names of any components they generate
  Branching to allow components to specify any modules they may have created
r12846@t0mlaptop (orig r12811):  rafl | 2010-02-04 06:18:46 +0000
Version 5.80020.

28 files changed:
Changes
Makefile.PL
TODO
lib/Catalyst.pm
lib/Catalyst/Component.pm
lib/Catalyst/Controller.pm
lib/Catalyst/Engine.pm
lib/Catalyst/Engine/CGI.pm
lib/Catalyst/Engine/HTTP.pm
lib/Catalyst/Runtime.pm
lib/Catalyst/Script/FastCGI.pm
lib/Catalyst/Script/Server.pm
lib/Catalyst/Test.pm
t/aggregate/catalyst_test_utf8.t [new file with mode: 0644]
t/aggregate/deprecated_test_import.t [new file with mode: 0644]
t/aggregate/live_component_controller_action_action.t
t/aggregate/live_component_controller_action_chained.t
t/aggregate/unit_core_component_generating.t [new file with mode: 0644]
t/aggregate/unit_core_engine_cgi-prepare_path.t
t/aggregate/unit_core_script_server.t
t/aggregate/unit_core_uri_for.t
t/aggregate/unit_load_catalyst_test.t
t/lib/TestApp.pm
t/lib/TestApp/Action/TestExtraArgsAction.pm [new file with mode: 0644]
t/lib/TestApp/Controller/Action/Action.pm
t/lib/TestApp/Model/Generating.pm [new file with mode: 0644]
t/lib/TestAppEncoding/Controller/Root.pm
t/live_component_controller_context_closure.t

diff --git a/Changes b/Changes
index e29a5a4..9023525 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,18 +1,85 @@
 # This file documents the revision history for Perl extension Catalyst.
 
+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.
+
+  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
+     the importer running is now deprecated and will issue a warning.
+     You should be saying use Catalyst::Test ();
+
+5.80017 2010-01-10 02:27:29
+
   Documentation:
    - Fix docs for ->forward method when passed a class name - this should
      be a component name (e.g. View::HTML, not a full class name, like
      MyApp::View::HTML).
 
   Bug fixes:
-   - Remove the erroneous --detach option from Catalyst::Script::FastCGI
-   - --daemon option to Catalyst::Script::FastCGI is fixed.
+   - --daemon and -d options to Catalyst::Script::FastCGI are fixed.
    - Fix the debug dump for applications which use Catalyst::Plugin::Session
      (RT#52898)
    - Fix regression in the case where mod_rewrite is being used to rewrite
      requests into a path below your application base introduced with the
      %2F related fixes in 5.80014_02.
+   - Do not crash on SIGHUP if Catalyst::Engine::HTTP->run is not passed the
+     argv key in the options hash.
+   - Correctly pass the arguments to Catalyst::Script::Server through to
+     Catalyst::Engine::HTTP->run so that the server can restart itself
+     with the correct options on SIGHUP.
+   - Require new MooseX::MethodAttributes to be compatible with Moose
+     versions >= 0.93_01
+   - Require new MooseX::Role::WithOverloading to be compatible with Moose
+     versions >= 0.93_01
+
+  Cleanups:
+    - Stop suppressing warnings from Class::C3::Adopt::NEXT now that most plugins
+      have been updated to not use NEXT. If you get warnings then please upgrade
+      your components or log a bug with the component author if an upgrade is
+      not available. The Class::C3::Adopt::NEXT documentation contains information
+      about how to suppress the warnings in your application if you need to.
 
 5.80016 2009-12-11 23:23:33
 
           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
index ba32c9d..b5eac5f 100644 (file)
@@ -17,14 +17,13 @@ all_from 'lib/Catalyst/Runtime.pm';
 
 requires 'List::MoreUtils';
 requires 'namespace::autoclean' => '0.09';
-requires 'namespace::clean';
-requires 'namespace::autoclean';
+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 'MooseX::MethodAttributes::Inheritable' => '0.17';
-requires 'MooseX::Role::WithOverloading' => '0.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';
diff --git a/TODO b/TODO
index 4a2b319..8fd77ad 100644 (file)
--- a/TODO
+++ b/TODO
@@ -5,12 +5,6 @@
 
      Test app: http://github.com/bobtfish/catalyst-app-bug-go_chain/tree/master
 
-   - Bricas' Exception blog post
-
-     http://bricas.vox.com/library/post/catalyst-exceptionclass.html
-
-     Broken by recent exception refactoring
-
 # Compatibility warnings to add:
 
   - $self->config should warn as config should only ever be called as a
index 564ba7b..495a715 100644 (file)
@@ -78,7 +78,7 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.80016';
+our $VERSION = '5.80020';
 $VERSION = eval $VERSION;
 
 sub import {
@@ -243,6 +243,9 @@ environment with CATALYST_DEBUG or <MYAPP>_DEBUG. The environment
 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
@@ -262,6 +265,14 @@ is replaced with the uppercased name of your application, any "::" in
 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';
@@ -331,7 +342,7 @@ all 'dies' within the called action. If you want C<die> to propagate you
 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:
@@ -923,6 +934,8 @@ You can enable debug mode in several ways:
 
 =back
 
+The first three also set the log level to 'debug'.
+
 Calling C<< $c->debug(1) >> has no effect.
 
 =cut
@@ -1246,8 +1259,19 @@ sub uri_for {
         $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;
+    s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
+    if (blessed $path) { # Action object only.
+        s|/|%2F|g for @args;
+    }
+
     if ( blessed($path) ) { # action object
-        my $captures = [ map { s|/|%2F|; $_; }
+        my $captures = [ map { s|/|%2F|g; $_; }
                         ( scalar @args && ref $args[0] eq 'ARRAY'
                          ? @{ shift(@args) }
                          : ()) ];
@@ -1338,6 +1362,20 @@ $c->uri_for >>.
 You can also pass in a Catalyst::Action object, in which case it is passed to
 C<< $c->uri_for >>.
 
+Note that although the path looks like a URI that dispatches to the wanted action, it is not a URI, but an internal path to that action.
+
+For example, if the action looks like:
+
+ package MyApp::Controller::Users;
+
+ sub lst : Path('the-list') {}
+
+You can use:
+
+ $c->uri_for_action('/users/lst')
+
+and it will create the URI /users/the-list.
+
 =back
 
 =cut
@@ -2219,8 +2257,11 @@ sub setup_components {
     }
 
     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);
@@ -2953,6 +2994,8 @@ numa: Dan Sully <daniel@cpan.org>
 
 obra: Jesse Vincent
 
+Octavian Rasnita
+
 omega: Andreas Marienborg
 
 Oleg Kostyuk <cub.uanic@gmail.com>
index fe0ef6f..1b2d462 100644 (file)
@@ -5,6 +5,7 @@ use Class::MOP;
 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 @@ sub BUILDARGS {
         } 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 @@ sub process {
           . " 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 @@ __END__
 
 =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 @@ C<< my $component_instance = $component->COMPONENT($app, $arguments); >>
 
 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 @@ when you forward to them. The default is an abstract method.
 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)
index 1d91b3c..9f52b3f 100644 (file)
@@ -255,9 +255,15 @@ sub create_action {
     my $class = (exists $args{attributes}{ActionClass}
                     ? $args{attributes}{ActionClass}[0]
                     : $self->_action_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,26 @@ of setting namespace to '' (the null string).
 
 Sets 'path_prefix', as described below.
 
+=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
+(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)
index c881d55..7ba4167 100644 (file)
@@ -280,7 +280,8 @@ sub finalize_error {
 </html>
 
 
-    # Trick IE
+    # Trick IE. Old versions of IE would display their own error page instead
+    # of ours if we'd give it less than 512 bytes.
     $c->res->{body} .= ( ' ' x 512 );
 
     # Return 500
index cabd343..4c0d9b9 100644 (file)
@@ -167,9 +167,9 @@ sub prepare_path {
             # incorrect.
             if (substr($req_uri, 0, 1) ne '/') {
                 my ($match) = $req_uri =~ m|^([^/]+)|;
-                my $idx = index($path_info, $match) + length($match);
-                my $path_info_part = substr($path_info, 0, $idx);
-                substr($req_uri, 0, length($match), $path_info_part);
+                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;
         }
@@ -196,7 +196,7 @@ sub prepare_path {
     my $query = $ENV{QUERY_STRING} ? '?' . $ENV{QUERY_STRING} : '';
     my $uri   = $scheme . '://' . $host . '/' . $path . $query;
 
-    $c->request->uri( bless \$uri, $uri_class );
+    $c->request->uri( bless(\$uri, $uri_class)->canonical );
 
     # set the base URI
     # base must end in a slash
index 62c5d0b..7f01795 100644 (file)
@@ -339,7 +339,7 @@ sub run {
         use Config;
         $ENV{PERL5LIB} .= join $Config{path_sep}, @INC;
 
-        exec $^X, $0, @{ $options->{argv} };
+        exec $^X, $0, @{ $options->{argv} || [] };
     }
 
     exit;
index 74d9ce1..cc994d2 100644 (file)
@@ -7,7 +7,7 @@ BEGIN { require 5.008004; }
 
 # Remember to update this in Catalyst as well!
 
-our $VERSION='5.80016';
+our $VERSION='5.80020';
 
 $VERSION = eval $VERSION;
 
index 271d575..60b4133 100644 (file)
@@ -27,7 +27,7 @@ has daemon => (
     traits        => [qw(Getopt)],
     isa           => Bool,
     is            => 'ro',
-    cmd_aliases   => 'd',
+    cmd_aliases   => [qw/d detach/], # Eww, detach is here as we fucked it up.. Deliberately not documented
     documentation => 'Daemonize (go into the background)',
 );
 
index 4fc199b..e1f1049 100644 (file)
@@ -190,6 +190,7 @@ sub _application_args {
         $self->port,
         $self->host,
         {
+           argv => $self->ARGV,
            map { $_ => $self->$_ } qw/
                 fork
                 keepalive
index 8776803..f987172 100644 (file)
@@ -103,6 +103,12 @@ our $default_host;
 
     sub import {
         my ($self, $class, $opts) = @_;
+        Carp::carp(
+qq{Importing Catalyst::Test without an application name is deprecated:\n
+Instead of saying: use Catalyst::Test;
+say: use Catalyst::Test (); # If you don't want to import a test app right now.
+or say: use Catalyst::Test 'MyApp'; # If you do want to import a test app.\n\n})
+        unless $class;
         $import->($self, '-all' => { class => $class });
         $opts = {} unless ref $opts eq 'HASH';
         $default_host = $opts->{default_host} if exists $opts->{default_host};
diff --git a/t/aggregate/catalyst_test_utf8.t b/t/aggregate/catalyst_test_utf8.t
new file mode 100644 (file)
index 0000000..d8eb56f
--- /dev/null
@@ -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;
diff --git a/t/aggregate/deprecated_test_import.t b/t/aggregate/deprecated_test_import.t
new file mode 100644 (file)
index 0000000..ee90eea
--- /dev/null
@@ -0,0 +1,16 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Catalyst::Test ();
+
+my $warn;
+{
+    local $SIG{__WARN__} = sub { $warn = shift; };
+    Catalyst::Test->import();
+}
+ok $warn;
+like $warn, qr/deprecated/;
+
+done_testing;
+
index fd2b4cd..8dda203 100644 (file)
@@ -10,7 +10,7 @@ our $iters;
 
 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 @@ sub run_tests {
         );
     }
 
+    {
+        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;
index b0af156..7977875 100644 (file)
@@ -1087,7 +1087,7 @@ sub run_tests {
         # 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' )
-            or diag "'$content' does not contain '$path'";
+            or diag("Expected $path, got $content");
     }
 }
 
diff --git a/t/aggregate/unit_core_component_generating.t b/t/aggregate/unit_core_component_generating.t
new file mode 100644 (file)
index 0000000..a518fce
--- /dev/null
@@ -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');
index f8b08ef..76bad62 100644 (file)
@@ -62,6 +62,31 @@ use Catalyst::Engine::CGI;
     is ''.$r->base, 'http://www.foo.com/';
 }
 
+# nginx example from espent with path /"foo"
+{
+    my $r = get_req (
+        PATH_INFO => '"foo"',
+        SCRIPT_NAME => '/',
+        REQUEST_URI => '/%22foo%22',
+    );
+    is ''.$r->path, '%22foo%22';
+    is ''.$r->uri, 'http://www.foo.com/%22foo%22';
+    is ''.$r->base, 'http://www.foo.com/';
+}
+
+# nginx example from espent with path /"foo" and the app based at /oslobilder
+{
+    my $r = get_req (
+        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/';
+}
+
+
 
 
 # FIXME - Test proxy logic
index c75cec6..b9ad60b 100644 (file)
@@ -89,6 +89,8 @@ sub testOption {
     };
     # First element of RUN_ARGS will be the script name, which we don't care about
     shift @TestAppToTestScripts::RUN_ARGS;
+    # Mangle argv into the options..
+    $resultarray->[-1]->{argv} = $argstring;
     is_deeply \@TestAppToTestScripts::RUN_ARGS, $resultarray, "is_deeply comparison " . join(' ', @$argstring);
 }
 
index 170e91b..da40bea 100644 (file)
@@ -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,21 @@ TODO: {
     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'
+    );
+}
+
+
+done_testing;
+
index fa8144c..036c3b8 100644 (file)
@@ -3,9 +3,7 @@
 use strict;
 use warnings;
 
-use FindBin;
-use lib         "$FindBin::Bin/../lib";
-use Test::More  tests => 61;
+use Test::More;
 use FindBin qw/$Bin/;
 use lib "$Bin/../lib";
 use Catalyst::Utils;
@@ -26,7 +24,7 @@ my %Meth    = (
 ### make sure we're not trying to connect to a remote host -- these are local tests
 local $ENV{CATALYST_SERVER};
 
-use_ok( $Class );
+use Catalyst::Test ();
 
 ### check available methods
 {   ### turn of redefine warnings, we'll get new subs exported
@@ -155,3 +153,4 @@ lives_ok {
     request(GET('/dummy'), []);
 } 'array additional param to request method ignored';
 
+done_testing;
index a2fc0b2..1e4d5c4 100644 (file)
@@ -20,7 +20,7 @@ our $VERSION = '0.01';
 
 TestApp->config( name => 'TestApp', root => '/some/dir' );
 
-if (eval { Class::MOP::load_class('CatalystX::LeakChecker'); 1 }) {
+if ($::setup_leakchecker && eval { Class::MOP::load_class('CatalystX::LeakChecker'); 1 }) {
     with 'CatalystX::LeakChecker';
 
     has leaks => (
diff --git a/t/lib/TestApp/Action/TestExtraArgsAction.pm b/t/lib/TestApp/Action/TestExtraArgsAction.pm
new file mode 100644 (file)
index 0000000..3cfb38b
--- /dev/null
@@ -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;
index 5049427..21d4f51 100644 (file)
@@ -3,7 +3,15 @@ package TestApp::Controller::Action::Action;
 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 @@ sub action_action_six : Global : ActionClass('~TestMyAction') {
     $c->forward('TestApp::View::Dump::Request');
 }
 
+sub action_action_seven : Global : ActionClass('~TestExtraArgsAction') {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
 1;
diff --git a/t/lib/TestApp/Model/Generating.pm b/t/lib/TestApp/Model/Generating.pm
new file mode 100644 (file)
index 0000000..24981e0
--- /dev/null
@@ -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;
index 391a2cd..a8987fb 100644 (file)
@@ -8,7 +8,11 @@ __PACKAGE__->config->{namespace} = '';
 
 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 @@ sub binary_utf8 : Local {
     $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) = @_;
 }
index 34318ea..767822d 100644 (file)
@@ -13,6 +13,8 @@ BEGIN {
 use FindBin;
 use lib "$FindBin::Bin/lib";
 
+BEGIN { $::setup_leakchecker = 1 }
+
 use Catalyst::Test 'TestApp';
 
 {