Merge 'trunk' into 'param_filtering'
Tomas Doran [Mon, 1 Mar 2010 19:10:02 +0000 (19:10 +0000)]
r12135@t0mlaptop (orig r12100):  t0m | 2009-12-01 02:16:08 +0000
Fix bug in Catalyst::Engine which could cause it to all go wrong if read returned '0' as per thread on mailing list re 'Wrong Content-Length value' and clarify docs about read and read_chunk methods in Catalyst::Engine
r12149@t0mlaptop (orig r12114):  t0m | 2009-12-01 04:19:44 +0000
The documentation example had the variables the opposite way round to my working nginx config. CLEARLY this meant the documentation needed the variables (but not their values) transposing. Yes, yes - I really am _that_ dumb.
r12181@t0mlaptop (orig r12146):  t0m | 2009-12-02 15:10:52 +0000
Changes, bump version
r12184@t0mlaptop (orig r12149):  t0m | 2009-12-02 18:58:14 +0000
Pod nits, rt#52370
r12185@t0mlaptop (orig r12150):  t0m | 2009-12-02 19:13:19 +0000
And that's what I get for not really applying the patch and doing it manually. Fail..
r12186@t0mlaptop (orig r12151):  gshank | 2009-12-02 21:52:21 +0000
add another failing test for Chained CaptureArgs preference

r12203@t0mlaptop (orig r12168):  t0m | 2009-12-03 17:15:17 +0000
I can't stand the over-long debug screens any more. Suggestions on how to do this in a less gross way?
r12244@t0mlaptop (orig r12209):  t0m | 2009-12-06 12:47:59 +0000
Win32 fix, kmx++
r12245@t0mlaptop (orig r12210):  t0m | 2009-12-06 13:04:50 +0000
Skip on win32, hopefully we'll get a better answer than this, but lets stop failing
r12253@t0mlaptop (orig r12218):  rafl | 2009-12-06 16:31:52 +0000
Undocument $request->user.
r12254@t0mlaptop (orig r12219):  autarch | 2009-12-06 18:44:36 +0000
Add restartdirectory as alias for restart_directory, for backcompat

r12255@t0mlaptop (orig r12220):  autarch | 2009-12-06 18:48:34 +0000
fix pod for Server script so options match actual attr name
r12257@t0mlaptop (orig r12222):  autarch | 2009-12-06 18:50:57 +0000
Doc change for --restartdirectory

r12260@t0mlaptop (orig r12225):  kmx | 2009-12-06 20:11:43 +0000
Win32 fix: reverting commit 12210 (after a discussion with t0m) - all tests pass on Win32/strawberry perl 5.8.9 and 5.10.1
r12287@t0mlaptop (orig r12252):  autarch | 2009-12-08 05:38:40 +0000
Don't default to localhost for --host

Tweak docs for --host to say it accepts a name or IP

r12288@t0mlaptop (orig r12253):  autarch | 2009-12-08 05:39:25 +0000
Doc --host change

r12291@t0mlaptop (orig r12256):  t0m | 2009-12-08 11:16:44 +0000
Fix tests from r12252, add comments to make the behavior explicit
r12306@t0mlaptop (orig r12271):  t0m | 2009-12-09 18:30:53 +0000
Regression for 5.80015 when rewriting an app, nanonyme++, Khisanth++
r12311@t0mlaptop (orig r12276):  t0m | 2009-12-09 20:21:13 +0000
Fixes port environment, RT#52604
r12312@t0mlaptop (orig r12277):  t0m | 2009-12-09 20:35:13 +0000
And more tests and fixing for the same thing
r12313@t0mlaptop (orig r12278):  t0m | 2009-12-09 20:50:18 +0000
Changelog
r12314@t0mlaptop (orig r12279):  t0m | 2009-12-09 20:54:53 +0000
More tests for the prepare_path thing, fix said tests, changelog
r12316@t0mlaptop (orig r12281):  t0m | 2009-12-09 21:36:13 +0000
Additional test
r12325@t0mlaptop (orig r12290):  t0m | 2009-12-10 09:46:10 +0000
Fix RT#52630
r12342@t0mlaptop (orig r12307):  t0m | 2009-12-11 12:44:55 +0000
Unfuck that as well
r12350@t0mlaptop (orig r12315):  t0m | 2009-12-11 23:25:35 +0000
Remove warning when running tests aggregated
r12351@t0mlaptop (orig r12316):  t0m | 2009-12-11 23:26:08 +0000
Changelog, bump version
r12352@t0mlaptop (orig r12317):  rafl | 2009-12-11 23:28:09 +0000
moar better warnings fix.
r12422@t0mlaptop (orig r12387):  t0m | 2009-12-15 10:21:32 +0000
Bug fix for issue reported on the mailing list by Toby Corkindale
r12466@t0mlaptop (orig r12431):  t0m | 2009-12-18 19:55:03 +0000
Fix RT#52898, __MOP__ removal breaking debug screen with C::P::Session
r12497@t0mlaptop (orig r12462):  t0m | 2009-12-22 14:19:36 +0000
Someone think of a less fugly way of doing this please? Fixes using rewrite rules to ask for a sub-path in your app with apache in some combinations..
r12528@t0mlaptop (orig r12493):  t0m | 2009-12-30 15:55:43 +0000
Fix regex special characters screwing things up by not using regexes
r12559@t0mlaptop (orig r12524):  t0m | 2010-01-04 20:52:10 +0000
Doc fix
r12560@t0mlaptop (orig r12525):  t0m | 2010-01-04 20:55:25 +0000
Clarify comment
r12564@t0mlaptop (orig r12529):  rafl | 2010-01-05 00:28:35 +0000
Stop supressing Adopt::NEXT warnings.
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.
r12870@t0mlaptop (orig r12835):  t0m | 2010-02-08 21:46:15 +0000
 r12572@t0mlaptop (orig r12537):  caelum | 2010-01-06 22:33:51 +0000
 branch to utf8-decode captures and args
 r12573@t0mlaptop (orig r12538):  caelum | 2010-01-06 22:56:59 +0000
 utf8::decode captures and args, and uri-escape captures
 r12574@t0mlaptop (orig r12539):  caelum | 2010-01-07 00:04:45 +0000
 add a test for the uri_for utf8 stuff
 r12869@t0mlaptop (orig r12834):  t0m | 2010-02-08 21:20:05 +0000
 Unfuck

r12889@t0mlaptop (orig r12853):  caelum | 2010-02-09 22:26:23 +0000
update Changes, put comment back in
r12890@t0mlaptop (orig r12854):  t0m | 2010-02-11 20:06:15 +0000
Fix typo
r12891@t0mlaptop (orig r12855):  t0m | 2010-02-11 20:36:22 +0000
First attempt to make this make more sense.
r12897@t0mlaptop (orig r12861):  rafl | 2010-02-14 11:30:23 +0000
Make the debug log say the cat version with all its digits.
r13014@t0mlaptop (orig r12978):  rafl | 2010-02-23 17:52:30 +0000
fix doc typo.

39 files changed:
Changes
Makefile.PL
TODO
lib/Catalyst.pm
lib/Catalyst/Component.pm
lib/Catalyst/Controller.pm
lib/Catalyst/Dispatcher.pm
lib/Catalyst/Engine.pm
lib/Catalyst/Engine/CGI.pm
lib/Catalyst/Engine/FastCGI.pm
lib/Catalyst/Engine/HTTP.pm
lib/Catalyst/Request.pm
lib/Catalyst/Runtime.pm
lib/Catalyst/Script/Create.pm
lib/Catalyst/Script/FastCGI.pm
lib/Catalyst/Script/Server.pm
lib/Catalyst/Test.pm
lib/Catalyst/Upgrading.pod
t/aggregate/catalyst_test_utf8.t [new file with mode: 0644]
t/aggregate/deprecated_test_import.t [new file with mode: 0644]
t/aggregate/error_page_dump.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 [new file with mode: 0644]
t/aggregate/unit_core_script_create.t
t/aggregate/unit_core_script_fastcgi.t
t/aggregate/unit_core_script_server.t
t/aggregate/unit_core_uri_for.t
t/aggregate/unit_core_uri_for_multibytechar.t
t/aggregate/unit_load_catalyst_test.t
t/deprecated.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/Controller/Action/Chained/CaptureArgs.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 a2ff652..de9104c 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,133 @@
 # This file documents the revision history for Perl extension Catalyst.
 
+  Bug fixed:
+   - uri_for will now escape unsafe chars in captures and encode utf8 chars
+
+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:
+   - --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
+
+  Bug fixes:
+
+   - Fix slurping a file to work correctly with binary on Win32 in the
+     encoding test controller.
+
+  Bug fixes in the new scripts (for applications which have been upgraded):
+
+   - Allow --restartdirectory as an option for the Server script, for
+     backwards compatibility. (Dave Rolsky)
+   - The --host option for the server script defaulted to localhost, rather
+     than listening on all interfaces, which was the previous default. (Dave
+     Rolsky)
+   - Restore -p option for pid file in the FastCGI server script.
+   - Fix the script environment variables MYAPP_PORT and MYAPP_RELOAD RT#52604
+   - Fix aliasing applications under non-root paths with mod_rewrite in
+     some apache versions where %ENV{SCRIPT_NAME} is set to the real name of
+     the script, by using $ENV{REDIRECT_URL} which contains the non-rewritten
+     URI.
+   - Fix usage display when myapp_create.pl is run with no arguments. RT#52630
+
+  New features:
+
+   - The __MOP__ hash element is suppressed from being dumped fully
+     (and instead stringified) when dumping the error screen to be
+     less packed with information of no use.
+
+  Documentation:
+
+   - Fix Pod nits (RT#52370)
+
+5.80015 2009-12-02 15:13:54
+  Bug fixes:
+   - Fix bug in Catalyst::Engine which would cause a request parsing to end
+     prematurely in the hypothetical case where calling $engine->read returned
+     the single character '0'.
+   - Fix failing tests when combined with new HTTP::Request::AsCGI
+
+  Documentation:
+   - Improved documentation on read and read_chunk methods in Catalyst::Engine.
+   - Fix reversal of SCRIPT_NAME and PATH_INFO in previously correct nginx
+     FastCGI documentation introduced in _02.
+
 5.80014_02 2009-12-01 00:55:23
   Bug fixes:
    - Fix reporting the wrong Content-Length if the response body is an
           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 9e74bee..ef99798 100644 (file)
@@ -78,12 +78,8 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.80014_02';
-
-{
-    my $dev_version = $VERSION =~ /_\d{2}$/;
-    *_IS_DEVELOPMENT_VERSION = sub () { $dev_version };
-}
+our $VERSION = '5.80020';
+our $PRETTY_VERSION = $VERSION;
 
 $VERSION = eval $VERSION;
 
@@ -97,11 +93,6 @@ sub import {
     my $caller = caller();
     return if $caller eq 'main';
 
-    # Kill Adopt::NEXT warnings if we're a non-RC version
-    unless (_IS_DEVELOPMENT_VERSION()) {
-        Class::C3::Adopt::NEXT->unimport(qr/^Catalyst::/);
-    }
-
     my $meta = Moose::Meta::Class->initialize($caller);
     unless ( $caller->isa('Catalyst') ) {
         my @superclasses = ($meta->superclasses, $class, 'Catalyst::Controller');
@@ -254,6 +245,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
@@ -273,6 +267,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';
@@ -332,8 +334,8 @@ call to forward.
 
     my $foodata = $c->forward('/foo');
     $c->forward('index');
-    $c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
-    $c->forward('MyApp::View::TT');
+    $c->forward(qw/Model::DBIC::Foo do_stuff/);
+    $c->forward('View::TT');
 
 Note that L<< forward|/"$c->forward( $action [, \@arguments ] )" >> implies
 an C<< eval { } >> around the call (actually
@@ -342,22 +344,22 @@ 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:
 
     $c->forward('foo') || return;
-    
+
 Another note is that C<< $c->forward >> always returns a scalar because it
 actually returns $c->state which operates in a scalar context.
 Thus, something like:
 
     return @array;
-    
-in an action that is forwarded to is going to return a scalar, 
+
+in an action that is forwarded to is going to return a scalar,
 i.e. how many items are in that array, which is probably not what you want.
-If you need to return an array then return a reference to it, 
+If you need to return an array then return a reference to it,
 or stash it like so:
 
     $c->stash->{array} = \@array;
@@ -417,9 +419,9 @@ sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
 
 =head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
 
-The relationship between C<go> and 
+The relationship between C<go> and
 L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >> is the same as
-the relationship between 
+the relationship between
 L<< forward|/"$c->forward( $class, $method, [, \@arguments ] )" >> and
 L<< detach|/"$c->detach( $action [, \@arguments ] )" >>. Like C<< $c->visit >>,
 C<< $c->go >> will perform a full dispatch on the specified action or method,
@@ -504,7 +506,7 @@ sub error {
 
 =head2 $c->state
 
-Contains the return value of the last executed action.   
+Contains the return value of the last executed action.
 Note that << $c->state >> operates in a scalar context which means that all
 values it returns are scalar.
 
@@ -802,7 +804,7 @@ component name will be returned.
 If Catalyst can't find a component by name, it will fallback to regex
 matching by default. To disable this behaviour set
 disable_component_resolution_regex_fallback to a true value.
-    
+
     __PACKAGE__->config( disable_component_resolution_regex_fallback => 1 );
 
 =cut
@@ -934,6 +936,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
@@ -1142,7 +1146,7 @@ EOF
 
     if ( $class->debug ) {
         my $name = $class->config->{name} || 'Application';
-        $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
+        $class->log->info("$name powered by Catalyst $Catalyst::PRETTY_VERSION");
     }
 
     # Make sure that the application class becomes immutable at this point,
@@ -1180,23 +1184,20 @@ EOF
     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.
 
-        my $app = shift;
-
-        ## do stuff, i.e., determine a primary key column for sessions stored in a DB
-
-        $app->next::method(@_);
+Example:
 
+    after setup_finalize => sub {
+        my $app = shift;
 
-    }
+        ## do stuff here..
+    };
 
 =cut
 
@@ -1215,7 +1216,7 @@ When used as a string, provides a textual URI.
 
 If no arguments are provided, the URI for the current action is returned.
 To return the current action and also provide @args, use
-C<< $c->uri_for( $c->action, @args ) >>. 
+C<< $c->uri_for( $c->action, @args ) >>.
 
 If the first argument is a string, it is taken as a public URI path relative
 to C<< $c->namespace >> (if it doesn't begin with a forward slash) or
@@ -1257,11 +1258,31 @@ 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;
+    foreach my $arg (@args) {
+        utf8::encode($arg) if utf8::is_utf8($arg);
+    }
+    s/([^$URI::uric])/$URI::Escape::escapes{$1}/go for @args;
+    if (blessed $path) { # Action object only.
+        s|/|%2F|g for @args;
+    }
+
     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) }
                          : ()) ];
+
+        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) {
@@ -1274,13 +1295,6 @@ sub uri_for {
 
     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
@@ -1340,6 +1354,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
@@ -2584,8 +2612,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);
@@ -3049,12 +3080,11 @@ There are a number of 'base' config variables which can be set:
 
 =item *
 
-C<default_model> - The default model picked if you say C<< $c->model >>. See L</$c->model($name)>.
+C<default_model> - The default model picked if you say C<< $c->model >>. See L<< /$c->model($name) >>.
 
 =item *
 
-C<default_view> - The default view to be rendered or returned when C<< $c->view >>. See L</$c->view($name)>.
-is called.
+C<default_view> - The default view to be rendered or returned when C<< $c->view >> is called. See L<< /$c->view($name) >>.
 
 =item *
 
@@ -3319,6 +3349,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 d82dfe1..135c578 100644 (file)
@@ -153,7 +153,7 @@ sub _command2action {
         $action = $self->_invoke_as_path( $c, "$command", \@args );
     }
 
-    # go to a component ( "MyApp::*::Foo" or $c->component("...")
+    # go to a component ( "View::Foo" or $c->component("...")
     # - a path or an object)
     unless ($action) {
         my $method = @extra_params ? $extra_params[0] : "process";
index 443975e..7ba4167 100644 (file)
@@ -108,6 +108,24 @@ is in debug mode, or a `please come back later` message otherwise.
 
 =cut
 
+sub _dump_error_page_element {
+    my ($self, $i, $element) = @_;
+    my ($name, $val)  = @{ $element };
+
+    # This is fugly, but the metaclass is _HUGE_ and demands waaay too much
+    # scrolling. Suggestions for more pleasant ways to do this welcome.
+    local $val->{'__MOP__'} = "Stringified: "
+        . $val->{'__MOP__'} if ref $val eq 'HASH' && exists $val->{'__MOP__'};
+
+    my $text = encode_entities( dump( $val ));
+    sprintf <<"EOF", $name, $text;
+<h2><a href="#" onclick="toggleDump('dump_$i'); return false">%s</a></h2>
+<div id="dump_$i">
+    <pre wrap="">%s</pre>
+</div>
+EOF
+}
+
 sub finalize_error {
     my ( $self, $c ) = @_;
 
@@ -138,14 +156,7 @@ sub finalize_error {
         my @infos;
         my $i = 0;
         for my $dump ( $c->dump_these ) {
-            my $name  = $dump->[0];
-            my $value = encode_entities( dump( $dump->[1] ));
-            push @infos, sprintf <<"EOF", $name, $value;
-<h2><a href="#" onclick="toggleDump('dump_$i'); return false">%s</a></h2>
-<div id="dump_$i">
-    <pre wrap="">%s</pre>
-</div>
-EOF
+            push @infos, $self->_dump_error_page_element($i, $dump);
             $i++;
         }
         $infos = join "\n", @infos;
@@ -269,7 +280,8 @@ EOF
 </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
@@ -327,7 +339,8 @@ sub prepare_body {
               if exists $appclass->config->{uploadtmp};
         }
 
-        while ( my $buffer = $self->read($c) ) {
+        # Check for definedness as you could read '0'
+        while ( defined ( my $buffer = $self->read($c) ) ) {
             $c->prepare_body_chunk($buffer);
         }
 
@@ -566,6 +579,10 @@ sub prepare_write { }
 
 =head2 $self->read($c, [$maxlength])
 
+Reads from the input stream by calling C<< $self->read_chunk >>.
+
+Maintains the read_length and read_position counters as data is read.
+
 =cut
 
 sub read {
@@ -583,6 +600,11 @@ sub read {
     my $readlen = ( $remaining > $maxlength ) ? $maxlength : $remaining;
     my $rc = $self->read_chunk( $c, my $buffer, $readlen );
     if ( defined $rc ) {
+        if (0 == $rc) { # Nothing more to read even though Content-Length
+                        # said there should be. FIXME - Warn in the log here?
+            $self->finalize_read;
+            return;
+        }
         $self->read_position( $self->read_position + $rc );
         return $buffer;
     }
@@ -595,7 +617,8 @@ sub read {
 =head2 $self->read_chunk($c, $buffer, $length)
 
 Each engine implements read_chunk as its preferred way of reading a chunk
-of data.
+of data. Returns the number of bytes read. A return of 0 indicates that
+there is no more data to be read.
 
 =cut
 
index 8fa1fca..4c0d9b9 100644 (file)
@@ -108,6 +108,8 @@ sub prepare_headers {
 
 =cut
 
+# Please don't touch this method without adding tests in
+# t/aggregate/unit_core_engine_cgi-prepare_path.t
 sub prepare_path {
     my ( $self, $c ) = @_;
     local (*ENV) = $self->env || \%ENV;
@@ -153,11 +155,24 @@ sub prepare_path {
     # Here we try to resurrect the original encoded URI from REQUEST_URI.
     my $path_info   = $ENV{PATH_INFO};
     if (my $req_uri = $ENV{REQUEST_URI}) {
-        if (defined $script_name) {
-            $req_uri =~ s/^\Q$script_name\E//;
-        }
+        $req_uri =~ s/^\Q$base_path\E//;
         $req_uri =~ s/\?.*$//;
-        $path_info = $req_uri if $req_uri;
+        if ($req_uri) {
+            # Note that if REQUEST_URI doesn't start with a /, then the user
+            # is probably using mod_rewrite or something to rewrite requests
+            # into a sub-path of their application..
+            # This means that REQUEST_URI needs information from PATH_INFO
+            # prepending to it to be useful, otherwise the sub path which is
+            # being redirected to becomes the app base address which is
+            # incorrect.
+            if (substr($req_uri, 0, 1) ne '/') {
+                my ($match) = $req_uri =~ m|^([^/]+)|;
+                my ($path_info_part) = $path_info =~ m|^(.*?\Q$match\E)|;
+                substr($req_uri, 0, length($match), $path_info_part)
+                    if $path_info_part;
+            }
+            $path_info = $req_uri;
+        }
     }
 
     # set the request URI
@@ -181,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 85b360c..9f7dfb2 100644 (file)
@@ -463,8 +463,8 @@ The server configuration block should look roughly like:
             fastcgi_param  CONTENT_TYPE       $content_type;
             fastcgi_param  CONTENT_LENGTH     $content_length;
 
-            fastcgi_param  PATH_INFO          /;
-            fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
+            fastcgi_param  SCRIPT_NAME        /;
+            fastcgi_param  PATH_INFO          $fastcgi_script_name;
             fastcgi_param  REQUEST_URI        $request_uri;
             fastcgi_param  DOCUMENT_URI       $document_uri;
             fastcgi_param  DOCUMENT_ROOT      $document_root;
@@ -491,13 +491,13 @@ simply include that file.
 =head3  Non-root configuration
 
 If you properly specify the PATH_INFO and SCRIPT_NAME parameters your
-application will be accessible at any path.  The PATH_INFO variable is the
-prefix of your application, and SCRIPT_NAME would be everything in addition.
+application will be accessible at any path. The SCRIPT_NAME variable is the
+prefix of your application, and PATH_INFO would be everything in addition.
 
 As an example, if your application is rooted at /myapp, you would configure:
 
-    fastcgi_param  PATH_INFO /myapp/;
-    fastcgi_param  SCRIPT_NAME $fastcgi_script_name;
+    fastcgi_param  SCRIPT_NAME /myapp/;
+    fastcgi_param  PATH_INFO   $fastcgi_script_name;
 
 C<$fastcgi_script_name> would be "/myapp/path/of/the/action".  Catalyst will
 process this accordingly and setup the application base as expected.
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 4b7de6d..ab5c0da 100644 (file)
@@ -673,14 +673,6 @@ sub uri_with {
     return $uri;
 }
 
-=head2 $req->user
-
-Returns the currently logged in user. B<Highly deprecated>, do not call,
-this will be removed in version 5.81. To retrieve the currently authenticated
-user, see C<< $c->user >> and C<< $c->user_exists >> in
-L<Catalyst::Plugin::Authentication>. For the C<REMOTE_USER> provided by the
-webserver, see C<< $req->remote_user >> below.
-
 =head2 $req->remote_user
 
 Returns the value of the C<REMOTE_USER> environment variable.
index d3c5e5d..cc994d2 100644 (file)
@@ -7,7 +7,7 @@ BEGIN { require 5.008004; }
 
 # Remember to update this in Catalyst as well!
 
-our $VERSION='5.80014_02';
+our $VERSION='5.80020';
 
 $VERSION = eval $VERSION;
 
index 7d318fe..05b4a66 100644 (file)
@@ -40,13 +40,13 @@ sub _build_helper_class { 'Catalyst::Helper' }
 sub run {
     my ($self) = @_;
 
-    $self->_exit_with_usage if !$self->ARGV->[0];
+    $self->_getopt_full_usage if !$self->ARGV->[0];
 
     my $helper_class = $self->helper_class;
     Class::MOP::load_class($helper_class);
     my $helper = $helper_class->new( { '.newfiles' => !$self->force, mech => $self->mechanize } );
 
-    $self->_exit_with_usage unless $helper->mk_component( $self->application_name, @ARGV );
+    $self->_getopt_full_usage unless $helper->mk_component( $self->application_name, @ARGV );
 
 }
 
index 977bcd6..60b4133 100644 (file)
@@ -17,7 +17,7 @@ has listen => (
 
 has pidfile => (
     traits        => [qw(Getopt)],
-    cmd_aliases   => 'pid',
+    cmd_aliases   => [qw/pid p/],
     isa           => Str,
     is            => 'ro',
     documentation => 'Specify a pidfile',
@@ -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)',
 );
 
@@ -55,14 +55,6 @@ has nproc => (
     documentation => 'Specify a number of child processes',
 );
 
-has detach => (
-    traits        => [qw(Getopt)],
-    cmd_aliases   => 'det',
-    isa           => Bool,
-    is            => 'ro',
-    documentation => 'Detach this FastCGI process',
-);
-
 sub _application_args {
     my ($self) = shift;
     return (
@@ -71,7 +63,7 @@ sub _application_args {
             nproc   => $self->nproc,
             pidfile => $self->pidfile,
             manager => $self->manager,
-            detach  => $self->detach,
+            detach  => $self->daemon,
             keep_stderr => $self->keeperr,
         }
     );
index 77b9d9b..e1f1049 100644 (file)
@@ -8,6 +8,7 @@ BEGIN {
 use Moose;
 use MooseX::Types::Common::Numeric qw/PositiveInt/;
 use MooseX::Types::Moose qw/ArrayRef Str Bool Int RegexpRef/;
+use Catalyst::Utils;
 use namespace::autoclean;
 
 with 'Catalyst::ScriptRole';
@@ -27,8 +28,8 @@ has host => (
     cmd_aliases   => 'h',
     isa           => Str,
     is            => 'ro',
-    default       => 'localhost',
-    documentation => 'Specify an IP on this host for the server to bind to',
+    # N.B. undef (the default) means we bind on all interfaces on the host.
+    documentation => 'Specify a hostname or IP on this host for the server to bind to',
 );
 
 has fork => (
@@ -45,7 +46,9 @@ has port => (
     cmd_aliases   => 'p',
     isa           => PositiveInt,
     is            => 'ro',
-    default       => 3000,
+    default       => sub {
+        Catalyst::Utils::env_value(shift->application_name, 'port') || 3000
+    },
     documentation => 'Specify a different listening port (to the default port 3000)',
 );
 
@@ -80,13 +83,15 @@ has restart => (
     cmd_aliases   => 'r',
     isa           => Bool,
     is            => 'ro',
-    default       => 0,
+    default       => sub {
+        Catalyst::Utils::env_value(shift->application_name, 'reload') || 0;
+    },
     documentation => 'use Catalyst::Restarter to detect code changes and restart the application',
 );
 
 has restart_directory => (
     traits        => [qw(Getopt)],
-    cmd_aliases   => 'rdir',
+    cmd_aliases   => [ 'rdir', 'restartdirectory' ],
     isa           => ArrayRef[Str],
     is            => 'ro',
     documentation => 'Restarter directory to watch',
@@ -185,6 +190,7 @@ sub _application_args {
         $self->port,
         $self->host,
         {
+           argv => $self->ARGV,
            map { $_ => $self->$_ } qw/
                 fork
                 keepalive
@@ -219,12 +225,12 @@ Catalyst::Script::Server - Catalyst test server
    -k     --keepalive      enable keep-alive connections
    -r     --restart        restart when files get modified
                        (defaults to false)
-   --rd   --restartdelay  delay between file checks
+   --rd   --restart_delay  delay between file checks
                       (ignored if you have Linux::Inotify2 installed)
-   --rr   --restartregex  regex match files that trigger
+   --rr   --restart_regex  regex match files that trigger
                       a restart when modified
                       (defaults to '\.yml$|\.yaml$|\.conf|\.pm$')
-   --rdir --restartdirectory  the directory to search for
+   --rdir --restart_directory  the directory to search for
                       modified files, can be set mulitple times
                       (defaults to '[SCRIPT_DIR]/..')
    --sym  --follow_symlinks   follow symlinks in search directories
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};
index 4fd14d8..66201a5 100644 (file)
@@ -217,7 +217,7 @@ been called, and will not call them again.
 
 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:
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;
+
diff --git a/t/aggregate/error_page_dump.t b/t/aggregate/error_page_dump.t
new file mode 100644 (file)
index 0000000..099f8da
--- /dev/null
@@ -0,0 +1,15 @@
+use strict;
+use warnings;
+use Test::More;
+use Test::Exception;
+
+use Catalyst::Engine;
+
+my $m = sub { Catalyst::Engine->_dump_error_page_element(@_) };
+
+lives_ok { $m->('Scalar' => ['foo' => 'bar']) };
+lives_ok { $m->('Array' => ['foo' => []]) };
+lives_ok { $m->('Hash' => ['foo' => {}]) }; 
+
+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 8a6a449..7977875 100644 (file)
@@ -931,6 +931,28 @@ sub run_tests {
         }
     }
 
+    #  PathPart('...') Args(1) should win over CaptureArgs(2) PathPart('')
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::CaptureArgs->base
+          TestApp::Controller::Action::Chained::CaptureArgs->test_one_arg
+          TestApp::Controller::Action::Chained::CaptureArgs->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # should dispatch to /base/test_one_arg
+        ok( my $response = request('http://localhost/captureargs/test/one'),
+            'Correct pathpart/arg ran' );
+        TODO: {
+        local $TODO = 'Known bug';
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'base; test_plus_arg; one;', 'Content OK' );
+        }
+    }
+
     #
     #   Args(0) should win over Args() if we actually have no arguments.
     {
@@ -1052,6 +1074,7 @@ sub run_tests {
         ['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];
@@ -1063,7 +1086,8 @@ sub run_tests {
             '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");
     }
 }
 
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');
diff --git a/t/aggregate/unit_core_engine_cgi-prepare_path.t b/t/aggregate/unit_core_engine_cgi-prepare_path.t
new file mode 100644 (file)
index 0000000..76bad62
--- /dev/null
@@ -0,0 +1,113 @@
+use strict;
+use warnings;
+use Test::More;
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+use TestApp;
+use Catalyst::Engine::CGI;
+
+# mod_rewrite to app root for non / based app
+{
+    my $r = get_req (
+        REDIRECT_URL => '/comics/',
+        SCRIPT_NAME => '/comics/dispatch.cgi',
+        REQUEST_URI => '/comics/',
+    );
+    is ''.$r->uri, 'http://www.foo.com/comics/';
+    is ''.$r->base, 'http://www.foo.com/comics/';
+}
+
+# mod_rewrite to sub path under app root for non / based app
+{
+    my $r = get_req (
+        PATH_INFO  => '/foo/bar.gif',
+        REDIRECT_URL => '/comics/foo/bar.gif',
+        SCRIPT_NAME => '/comics/dispatch.cgi',
+        REQUEST_URI => '/comics/foo/bar.gif',
+    );
+    is ''.$r->uri, 'http://www.foo.com/comics/foo/bar.gif';
+    is ''.$r->base, 'http://www.foo.com/comics/';
+}
+
+# Standard CGI hit for non / based app
+{
+    my $r = get_req (
+        PATH_INFO => '/static/css/blueprint/screen.css',
+        SCRIPT_NAME => '/~bobtfish/Gitalist/script/gitalist.cgi',
+        REQUEST_URI => '/~bobtfish/Gitalist/script/gitalist.cgi/static/css/blueprint/screen.css',
+    );
+    is ''.$r->uri, 'http://www.foo.com/~bobtfish/Gitalist/script/gitalist.cgi/static/css/blueprint/screen.css';
+    is ''.$r->base, 'http://www.foo.com/~bobtfish/Gitalist/script/gitalist.cgi/';
+}
+# / %2F %252F escaping case.
+{
+    my $r = get_req (
+        PATH_INFO => '/%2F/%2F',
+        SCRIPT_NAME => '/~bobtfish/Gitalist/script/gitalist.cgi',
+        REQUEST_URI => '/~bobtfish/Gitalist/script/gitalist.cgi/%252F/%252F',
+    );
+    is ''.$r->uri, 'http://www.foo.com/~bobtfish/Gitalist/script/gitalist.cgi/%252F/%252F';
+    is ''.$r->base, 'http://www.foo.com/~bobtfish/Gitalist/script/gitalist.cgi/';
+}
+
+# Using rewrite rules to ask for a sub-path in your app.
+# E.g. RewriteRule ^(.*)$ /path/to/fastcgi/domainprofi.fcgi/iframeredirect$1 [L,NS]
+{
+    my $r = get_req (
+        PATH_INFO => '/iframeredirect/info',
+        SCRIPT_NAME => '',
+        REQUEST_URI => '/info',
+    );
+    is ''.$r->uri, 'http://www.foo.com/iframeredirect/info';
+    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
+#       - Test query string
+#       - Test non standard port numbers
+#       - Test // in PATH_INFO
+#       - Test scheme (secure request on port 80)
+
+sub get_req {
+    my %template = (
+        HTTP_HOST => 'www.foo.com',
+        PATH_INFO => '/',
+    );
+
+    local %ENV = (%template, @_);
+
+    my $i = TestApp->new;
+    $i->engine(Catalyst::Engine::CGI->new);
+    $i->engine->prepare_path($i);
+    return $i->req;
+}
+
+done_testing;
+
index 588cfd5..68e2458 100644 (file)
@@ -12,7 +12,7 @@ use lib "$Bin/../lib";
     use Moose;
     extends 'Catalyst::Script::Create';
     our $help;
-    sub _exit_with_usage { $help++ }
+    sub _getopt_full_usage { $help++ }
 }
 
 {
index 7d4da0f..b5d3ea4 100644 (file)
@@ -19,12 +19,13 @@ testOption( [ qw|-l /tmp/foo| ], ['/tmp/foo', opthash()] );
 testOption( [ qw/-l 127.0.0.1:3000/ ], ['127.0.0.1:3000', opthash()] );
 
 #daemonize           -d --daemon
-testOption( [ qw/-d/ ], [undef, opthash()] );
-testOption( [ qw/--daemon/ ], [undef, opthash()] );
+testOption( [ qw/-d/ ], [undef, opthash(detach => 1)] );
+testOption( [ qw/--daemon/ ], [undef, opthash(detach => 1)] );
 
-# pidfile        -pidfile                  --pid --pidfile
+# pidfile        -pidfile -p                 --pid --pidfile
 testOption( [ qw/--pidfile cat.pid/ ], [undef, opthash(pidfile => 'cat.pid')] );
 testOption( [ qw/--pid cat.pid/ ], [undef, opthash(pidfile => 'cat.pid')] );
+testOption( [ qw/-p cat.pid/ ], [undef, opthash(pidfile => 'cat.pid')] );
 
 # manager
 testOption( [ qw/--manager foo::bar/ ], [undef, opthash(manager => 'foo::bar')] );
@@ -38,10 +39,6 @@ testOption( [ qw/-e/ ], [undef, opthash(keep_stderr => 1)] );
 testOption( [ qw/--nproc 6/ ], [undef, opthash(nproc => 6)] );
 testOption( [ qw/--n 6/ ], [undef, opthash(nproc => 6)] );
 
-# detach
-testOption( [ qw/--detach/ ], [undef, opthash(detach => 1)] );
-testOption( [ qw/--det/ ], [undef, opthash(detach => 1)] );
-
 done_testing;
 
 sub testOption {
index 694b75a..b9ad60b 100644 (file)
@@ -12,7 +12,8 @@ use Catalyst::Script::Server;
 my $testopts;
 
 # Test default (no opts/args behaviour)
-testOption( [ qw// ], ['3000', 'localhost', opthash()] );
+# Note undef for host means we bind to all interfaces.
+testOption( [ qw// ], ['3000', undef, opthash()] );
 
 # Old version supports long format opts with either one or two dashes.  New version only supports two.
 #                Old                       New
@@ -23,31 +24,48 @@ testOption( [ qw/--host testhost/ ], ['3000', 'testhost', opthash()] );
 testOption( [ qw/-h testhost/ ], ['3000', 'testhost', opthash()] );
 
 # port           -p -port --port           -l --listen
-testOption( [ qw/-p 3001/ ], ['3001', 'localhost', opthash()] );
-testOption( [ qw/--port 3001/ ], ['3001', 'localhost', opthash()] );
+testOption( [ qw/-p 3001/ ], ['3001', undef, opthash()] );
+testOption( [ qw/--port 3001/ ], ['3001', undef, opthash()] );
+{
+    local $ENV{TESTAPPTOTESTSCRIPTS_PORT} = 5000;
+    testOption( [ qw// ], [5000, undef, opthash()] );
+}
+{
+    local $ENV{CATALYST_PORT} = 5000;
+    testOption( [ qw// ], [5000, undef, opthash()] );
+}
 
 # fork           -f -fork --fork           -f --fork
-testOption( [ qw/--fork/ ], ['3000', 'localhost', opthash(fork => 1)] );
-testOption( [ qw/-f/ ], ['3000', 'localhost', opthash(fork => 1)] );
+testOption( [ qw/--fork/ ], ['3000', undef, opthash(fork => 1)] );
+testOption( [ qw/-f/ ], ['3000', undef, opthash(fork => 1)] );
 
 # pidfile        -pidfile                  --pid --pidfile
-testOption( [ qw/--pidfile cat.pid/ ], ['3000', 'localhost', opthash(pidfile => "cat.pid")] );
-testOption( [ qw/--pid cat.pid/ ], ['3000', 'localhost', opthash(pidfile => "cat.pid")] );
+testOption( [ qw/--pidfile cat.pid/ ], ['3000', undef, opthash(pidfile => "cat.pid")] );
+testOption( [ qw/--pid cat.pid/ ], ['3000', undef, opthash(pidfile => "cat.pid")] );
 
 # keepalive      -k -keepalive --keepalive -k --keepalive
-testOption( [ qw/-k/ ], ['3000', 'localhost', opthash(keepalive => 1)] );
-testOption( [ qw/--keepalive/ ], ['3000', 'localhost', opthash(keepalive => 1)] );
+testOption( [ qw/-k/ ], ['3000', undef, opthash(keepalive => 1)] );
+testOption( [ qw/--keepalive/ ], ['3000', undef, opthash(keepalive => 1)] );
 
 # symlinks       -follow_symlinks          --sym --follow_symlinks
-testOption( [ qw/--follow_symlinks/ ], ['3000', 'localhost', opthash(follow_symlinks => 1)] );
-testOption( [ qw/--sym/ ], ['3000', 'localhost', opthash(follow_symlinks => 1)] );
+testOption( [ qw/--follow_symlinks/ ], ['3000', undef, opthash(follow_symlinks => 1)] );
+testOption( [ qw/--sym/ ], ['3000', undef, opthash(follow_symlinks => 1)] );
 
 # background     -background               --bg --background
-testOption( [ qw/--background/ ], ['3000', 'localhost', opthash(background => 1)] );
-testOption( [ qw/--bg/ ], ['3000', 'localhost', opthash(background => 1)] );
+testOption( [ qw/--background/ ], ['3000', undef, opthash(background => 1)] );
+testOption( [ qw/--bg/ ], ['3000', undef, opthash(background => 1)] );
 
 # restart        -r -restart --restart     -R --restart
 testRestart( ['-r'], restartopthash() );
+{
+    local $ENV{TESTAPPTOTESTSCRIPTS_RELOAD} = 1;
+    testRestart( [], restartopthash() );
+}
+{
+    local $ENV{CATALYST_RELOAD} = 1;
+    testRestart( [], restartopthash() );
+}
+
 # restart dly    -rd -restartdelay         --rd --restart_delay
 testRestart( ['-r', '--rd', 30], restartopthash(sleep_interval => 30) );
 testRestart( ['-r', '--restart_delay', 30], restartopthash(sleep_interval => 30) );
@@ -71,12 +89,15 @@ 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);
 }
 
 sub testRestart {
     my ($argstring, $resultarray) = @_;
     my $app = _build_testapp($argstring);
+    ok $app->restart, 'App is in restart mode';
     my $args = {$app->_restarter_args};
     is_deeply delete $args->{argv}, $argstring, 'argv is arg string';
     is ref(delete $args->{start_sub}), 'CODE', 'Closure to start app present';
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 3320491..6f5d8ae 100644 (file)
@@ -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 @@ is($context->req->uri_with({ name => '村瀬大輔' }), $uri_with_multibyte, 'ur
 # 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;
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 d9f90e0..307181b 100644 (file)
@@ -39,7 +39,4 @@ is( $mvc_warnings, 1, 'Get the ::MVC:: warning' );
 ok( my $response = request('http://localhost/'), 'Request' );
 is( $response->header('X-Catalyst-Plugin-Deprecated'), '1', 'NEXT plugin ran correctly' );
 
-SKIP: {
-    skip 'non-dev release', 1 unless Catalyst::_IS_DEVELOPMENT_VERSION();
-    is( $warnings, 1, 'Got one and only one Adopt::NEXT warning');
-}
+is( $warnings, 1, 'Got one and only one Adopt::NEXT warning');
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;
index fb8320e..d42ab67 100644 (file)
@@ -5,15 +5,16 @@ use strict;
 use base qw( Catalyst::Controller );
 
 #
-#   This controller builds two patterns of URI:
+#   This controller build the following patterns of URI:
 #      /captureargs/*/*
 #      /captureargs/*/*/edit
 #      /captureargs/*
 #      /captureargs/*/edit
+#      /captureargs/test/*
 #   It will output the arguments they got passed to @_ after the
 #   context object. 
-#   /captureargs/one/edit should not dispatch to
-#   /captureargs/*/*
+#   /captureargs/one/edit should not dispatch to /captureargs/*/*
+#   /captureargs/test/one should not dispatch to /captureargs/*/*
 
 sub base  :Chained('/') PathPart('captureargs') CaptureArgs(0) {
     my ( $self, $c, $arg ) = @_;
@@ -50,6 +51,11 @@ sub view_one_arg :Chained('one_arg') PathPart('') Args(0) {
     push @{ $c->stash->{ passed_args } }, 'view_one_arg';
 }
 
+sub test_plus_arg :Chained('base') PathPart('test') Args(1) {
+    my ( $self, $c, $arg ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'test_plus_arg', $arg;
+}
+
 
 sub end : Private {
     my ( $self, $c ) = @_;
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 b5b3eeb..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 $!; 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';
 
 {