Merge 'trunk' into 'deprecate_appclass_actions'
Tomas Doran [Mon, 7 Sep 2009 20:35:57 +0000 (20:35 +0000)]
r11024@t0mlaptop (orig r11023):  caelum | 2009-08-01 20:04:08 +0100
allow uri_for($controller_instance)
r11035@t0mlaptop (orig r11034):  t0m | 2009-08-05 20:39:01 +0100
Require perl 5.8.6
r11038@t0mlaptop (orig r11037):  hobbs | 2009-08-06 10:57:02 +0100
Add a method to the stats object to get the request start time.

r11048@t0mlaptop (orig r11047):  t0m | 2009-08-07 01:15:04 +0100
Fix the perl version required there also
r11049@t0mlaptop (orig r11048):  t0m | 2009-08-07 01:24:17 +0100
Blow up if we're in author mode and don't have the right M::I extensions
r11050@t0mlaptop (orig r11049):  t0m | 2009-08-07 01:57:21 +0100
Bump MX::MA dep for anon class tests
r11058@t0mlaptop (orig r11057):  gbjk | 2009-08-07 17:45:03 +0100
DispatchType::Chained fix for default args attribute to handle Args(0) vs Args() at depth.

r11059@t0mlaptop (orig r11058):  gbjk | 2009-08-07 18:17:15 +0100
DispatchType::Chained fix failing test of Args(0) vs Args(0) on surface

r11062@t0mlaptop (orig r11061):  gbjk | 2009-08-07 22:17:22 +0100
Engine::HTTP - Fix paths for HTTP requests with scheme and domain in URI.

r11064@t0mlaptop (orig r11063):  groditi | 2009-08-08 22:54:04 +0100
make debug output prettier with large widths
r11065@t0mlaptop (orig r11064):  groditi | 2009-08-08 22:54:46 +0100
oops debug output got leaked in
r11069@t0mlaptop (orig r11068):  t0m | 2009-08-09 13:36:20 +0100
Fix RT#48555
r11070@t0mlaptop (orig r11069):  t0m | 2009-08-09 13:36:55 +0100
Updates changelog
r11071@t0mlaptop (orig r11070):  t0m | 2009-08-09 15:22:21 +0100
Rewrite fixes for RT#48555
r11123@t0mlaptop (orig r11122):  t0m | 2009-08-11 22:49:37 +0100
Unfuck Catalyst::View::JSON
r11125@t0mlaptop (orig r11124):  t0m | 2009-08-11 23:32:47 +0100
Apply patch from RT#48623 to fix headers in Engine::HTTP
r11127@t0mlaptop (orig r11126):  rjbs | 2009-08-12 00:33:18 +0100
svn merge -r 11123:11125 branches/locate_components/ trunk/
r11128@t0mlaptop (orig r11127):  rjbs | 2009-08-12 00:34:12 +0100
add changelog entry for merged locate_components branch
r11130@t0mlaptop (orig r11129):  t0m | 2009-08-12 01:15:51 +0100
Tiny change to make the error make more sense
r11132@t0mlaptop (orig r11131):  t0m | 2009-08-12 02:09:09 +0100
Split test out into a more proper app, so that the test no longer relies on the metaclass initialization hacking occurring in ->setup_component, as I want to move it
r11133@t0mlaptop (orig r11132):  t0m | 2009-08-12 02:11:07 +0100
Blow up rather than failing to call ->can if everything is totally screwed
r11134@t0mlaptop (orig r11133):  rafl | 2009-08-12 03:54:52 +0100
Fix POD refering to CGI::Cookie. We're using CGI::Simple::Cookie.

Courtesy of Forrest Cahoon.
r11135@t0mlaptop (orig r11134):  t0m | 2009-08-12 12:03:06 +0100
Make the code much clearer about what is going on, and remove the horrible map and grep which I hated.
r11140@t0mlaptop (orig r11139):  rafl | 2009-08-16 10:19:58 +0100
Do at least one (possibly empty) write when reading the response body from a filehandle.
r11145@t0mlaptop (orig r11144):  jshirley | 2009-08-17 22:33:17 +0100
Adding and documented X-Forwarded-Port
r11146@t0mlaptop (orig r11145):  t0m | 2009-08-17 23:08:19 +0100
Capitalisation fixes in Changelog
r11147@t0mlaptop (orig r11146):  t0m | 2009-08-17 23:11:34 +0100
Add _component_name stuff to Changes
r11148@t0mlaptop (orig r11147):  jshirley | 2009-08-17 23:13:05 +0100
Conflict resolution
r11149@t0mlaptop (orig r11148):  hobbs | 2009-08-17 23:24:46 +0100
Changelog for r11037

r11150@t0mlaptop (orig r11149):  t0m | 2009-08-18 00:14:38 +0100
Switch to catalyst_component_name
r11154@t0mlaptop (orig r11153):  ferz | 2009-08-18 07:55:14 +0100
Test case using Exception::Class

r11155@t0mlaptop (orig r11154):  ferz | 2009-08-18 12:19:40 +0100
drop POD comments.

r11166@t0mlaptop (orig r11165):  t0m | 2009-08-19 20:03:01 +0100
Move test to make more sense in my idea of the naming scheme - t/dead_ is for tests which check the app pukes, which this shouldn't
r11167@t0mlaptop (orig r11166):  t0m | 2009-08-19 20:04:59 +0100
Fail commit was fail. Back out the part I didn't want
r11168@t0mlaptop (orig r11167):  t0m | 2009-08-19 20:10:06 +0100
Remove r11058 - the commit message is lies, it does not fix the TODO test
r11169@t0mlaptop (orig r11168):  t0m | 2009-08-19 21:21:44 +0100
Back out r11057 which breaks one of the chained tests, whilst not fixing the bug in question
r11170@t0mlaptop (orig r11169):  t0m | 2009-08-19 21:29:16 +0100
Clean up test app for the exception test, as we don't want to depend on Test::Class thanks
r11171@t0mlaptop (orig r11170):  rafl | 2009-08-19 21:45:45 +0100
Changelog Engine::finalize_body changes.
r11181@t0mlaptop (orig r11180):  gbjk | 2009-08-21 14:07:54 +0100
Changelog update for previous Catalyst::Engine::HTTP fix.

r11182@t0mlaptop (orig r11181):  rafl | 2009-08-21 16:51:26 +0100
Now we don't have the broken restarter engine anymore, we conflict with old Catalyst::Devel versions, that don't have the new restarter yet.
r11183@t0mlaptop (orig r11182):  rafl | 2009-08-21 17:12:57 +0100
Conflict with the latest mason view, which blows up because of the new component_name constructor arg.
r11184@t0mlaptop (orig r11183):  rafl | 2009-08-21 17:13:05 +0100
Version 5.80008.
r11190@t0mlaptop (orig r11189):  t0m | 2009-08-21 20:54:58 +0100
Fix and tests for big issue in 5.80008
r11191@t0mlaptop (orig r11190):  rafl | 2009-08-21 21:28:30 +0100
Version 5.80009.
r11193@t0mlaptop (orig r11192):  rafl | 2009-08-21 21:55:25 +0100
DOH! do more than one read, if necessary.
r11194@t0mlaptop (orig r11193):  rafl | 2009-08-21 22:22:36 +0100
Do what we want instead of exiting a sub via last.
r11195@t0mlaptop (orig r11194):  rafl | 2009-08-21 22:22:45 +0100
Add test for sending the body from a filehandle with more data than the default chunksize of 64k.
r11196@t0mlaptop (orig r11195):  rafl | 2009-08-21 22:31:38 +0100
Changelogging.
r11197@t0mlaptop (orig r11196):  rafl | 2009-08-21 22:41:05 +0100
Version 5.80010.
r11215@t0mlaptop (orig r11214):  rafl | 2009-08-22 20:56:53 +0100
Remove leftovers of the restarter engine.

The removed code caused test failures, which weren't apparent due to installed
copies still being available in everyone's @INC.
r11218@t0mlaptop (orig r11217):  rafl | 2009-08-23 12:46:42 +0100
Changelogging.
r11219@t0mlaptop (orig r11218):  rafl | 2009-08-23 12:55:48 +0100
Version 5.80011.
r11221@t0mlaptop (orig r11220):  rafl | 2009-08-23 19:42:17 +0100
Failing test for component loading
r11233@t0mlaptop (orig r11232):  t0m | 2009-08-24 13:51:03 +0100
Test fixes for if CATALYST_DEBUG is set to 1.
r11239@t0mlaptop (orig r11238):  t0m | 2009-08-25 12:25:54 +0100
0003-Remove-diag-message.patch (marcus)
r11240@t0mlaptop (orig r11239):  t0m | 2009-08-25 12:26:15 +0100
Fix duplicate components
r11252@t0mlaptop (orig r11251):  frew | 2009-08-26 20:00:01 +0100
Look!  I'm famous!  (See Catalyst-Devel)
r11254@t0mlaptop (orig r11253):  dandv | 2009-08-27 01:56:26 +0100
POD addition: $c->req->body returns a string or a File::Temp object
r11278@t0mlaptop (orig r11277):  t0m | 2009-09-01 02:07:23 +0100
Nuke skipped test which will never pass
r11279@t0mlaptop (orig r11278):  t0m | 2009-09-01 02:07:47 +0100
Author tests
r11280@t0mlaptop (orig r11279):  t0m | 2009-09-01 02:09:29 +0100
t/author in MANFEST
r11281@t0mlaptop (orig r11280):  t0m | 2009-09-01 02:10:46 +0100
Stop remote tests breaking everything, and force authors to run some remote tests.
r11282@t0mlaptop (orig r11281):  t0m | 2009-09-01 02:11:33 +0100
Stop calling class data methods on instances + commented out warning
r11283@t0mlaptop (orig r11282):  t0m | 2009-09-01 02:11:45 +0100
Changelog
r11300@t0mlaptop (orig r11292):  t0m | 2009-09-01 15:11:05 +0100
Bump versions back to 5.8.4
r11301@t0mlaptop (orig r11293):  t0m | 2009-09-01 15:32:46 +0100
Changes tweaks
r11307@t0mlaptop (orig r11299):  t0m | 2009-09-02 03:03:58 +0100
Changelogging
r11361@t0mlaptop (orig r11331):  t0m | 2009-09-07 15:45:01 +0100
Fix hash key name back to what it used to be for compat, keeping renamed accessor where it was. Tests for this breakage to follow
r11363@t0mlaptop (orig r11333):  t0m | 2009-09-07 21:19:40 +0100
Test for r11331 + fix to only report each action name once from get_action_methods
r11364@t0mlaptop (orig r11334):  t0m | 2009-09-07 21:21:52 +0100
I'm an idiot, that totally doesn't work. remove.
r11365@t0mlaptop (orig r11335):  t0m | 2009-09-07 21:25:53 +0100
AGH. Too tired to be doing this, fucked it up again
r11366@t0mlaptop (orig r11336):  t0m | 2009-09-07 21:33:31 +0100
Fix duplicate results from get_action_methods. Q. Why didn't I just do that first time round? A: Am idiot.

52 files changed:
Changes
MANIFEST.SKIP
Makefile.PL
TODO
lib/Catalyst.pm
lib/Catalyst/Action.pm
lib/Catalyst/ClassData.pm
lib/Catalyst/Component.pm
lib/Catalyst/Controller.pm
lib/Catalyst/DispatchType/Chained.pm
lib/Catalyst/DispatchType/Path.pm
lib/Catalyst/DispatchType/Regex.pm
lib/Catalyst/Dispatcher.pm
lib/Catalyst/Engine.pm
lib/Catalyst/Engine/CGI.pm
lib/Catalyst/Engine/HTTP.pm
lib/Catalyst/Request.pm
lib/Catalyst/Response.pm
lib/Catalyst/Runtime.pm
lib/Catalyst/Stats.pm
t/aggregate/live_component_controller_action_index_or_default.t
t/aggregate/live_component_controller_action_path_matchsingle.t
t/aggregate/live_component_controller_action_regexp.t
t/aggregate/live_component_controller_action_streaming.t
t/aggregate/live_component_controller_anon.t
t/aggregate/live_component_view_single.t
t/aggregate/live_engine_request_headers.t
t/aggregate/live_engine_request_remote_user.t
t/aggregate/unit_core_uri_for_action.t
t/author/optional_http-server.t [moved from t/optional_http-server.t with 61% similarity]
t/caf_backcompat.t
t/cdi_backcompat_plugin_accessor_override.t [deleted file]
t/custom_exception_class_simple.t [new file with mode: 0644]
t/deprecated.t
t/lib/TestApp.pm
t/lib/TestApp/Action/TestMyAction.pm
t/lib/TestApp/Controller/Action/Streaming.pm
t/lib/TestApp/Controller/Anon.pm
t/lib/TestAppClassExceptionSimpleTest.pm [new file with mode: 0644]
t/lib/TestAppNonMooseController.pm [new file with mode: 0644]
t/lib/TestAppNonMooseController/Controller/Foo.pm [new file with mode: 0644]
t/lib/TestAppNonMooseController/ControllerBase.pm [new file with mode: 0644]
t/optional_http-server-restart.t
t/unit_controller_actions.t [new file with mode: 0644]
t/unit_core_classdata.t
t/unit_core_component_loading.t
t/unit_core_plugin.t
t/unit_core_setup.t
t/unit_core_setup_log.t
t/unit_core_setup_stats.t
t/unit_metaclass_compat_non_moose_controller.t
t/unit_stats.t

diff --git a/Changes b/Changes
index b0d8a94..c268650 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,27 +1,98 @@
 # This file documents the revision history for Perl extension Catalyst.
 
   Bug fixes:
+     - Fix t/optional_http-server.t test.
+     - Fix t/optional_http-server-restart.t test.
+     - Fix duplicate components being loaded at setup time, each component is
+       now loaded at most once + tests.
+     - Fix backward compatibility - hash key configured actions are stored in
+       is returned to 'actions'.
+     - Fix get_action_methods returning duplicate methods when a method is both
+       decorated with method attributes and set as an action in config.
+
+  Refactoring / cleanups:
+     - Reduce minimum supported perl version from 5.8.6 to 5.8.4 as there are
+       many people still running/testing this version with no known issues.
+
+  Tests:
+     - Make the optional_http_server.t test an author only test which must be
+       run by authors to stop it being broken again.
+     - Fix recursion warnings in the test suites.
+
+5.80011 2009-08-23 13:48:15
+
+  Bug fixes:
+      - Remove leftovers of the restarter engine. The removed code caused test
+        failures, which weren't apparent for anyone still having an old version
+        installed in @INC.
+
+5.80010 2009-08-21 23:32:15
+
+  Bug fixes:
+      - Fix and add tests for a regression introduced by 5.80008.
+        Catalyst::Engine is now able to send out data from filehandles larger
+        than the default chunksize of 64k again.
+
+5.80009 2009-08-21 22:21:08
+
+  Bug fixes:
+      - Fix and add tests for generating inner packages inside the COMPONENT
+        method, and those packages being correctly registered as components.
+        This fixes Catalyst::Model::DBIC among others.
+
+5.80008 2009-08-21 17:47:30
+
+  Bug fixes:
        - Fix replace_constructor warning to actually work if you make your
          application class immutable without that option.
        - Depend on Module::Pluggable 3.9 to prevent a bug wherein components
          in inner packages might not be registered. This especially affected
          tests.
        - Catalyst::Engine::FastCGI - relax the check for versions of Microsoft
-         IIS. Provides compatibility with Windows 2008 R2 as well as 
+         IIS. Provides compatibility with Windows 2008 R2 as well as
          (hopefully) future versions.
+       - In tests which depend on the values of environment variables,
+         localise the environment, then delete only relevant environment
+         variables (RT#48555)
+       - Fix issue with Engine::HTTP not sending headers properly in some cases
+         (RT#48623)
+       - Make Catalyst::Engine write at least once when finalizing the response
+         body from a filehandle, even if the write is empty. This avoids fail
+         when trying to send out an empty response body from a filehandle.
+       - Catalyst::Engine::HTTP - Accept a fully qualified absolute URI in the
+         Request-URI of the Request-Line
 
   Refactoring / cleanups:
        - Deleted the Restarter engine and its Watcher code. Use the
          new Catalyst::Restarter in a recent Catalyst::Devel instead.
-       - New unit test for Catalyst::Action 'unit_core_action.t' (groditi)
+       - New unit test for Catalyst::Action 'unit_core_action.t'
+       - Bump minimum supported perl version from 5.8.1 to 5.8.6 as there are
+         known issues with 5.8.3.
+       - Debug output uses dynamic column sizing to create more readable output
+         when using a larger $ENV{COLUMNS} setting. (groditi)
 
   New features:
-       - private_path method for Catalyst::Action + docs + tests (groditi)
+       - Added private_path method for Catalyst::Action
+       - Allow uri_for($controller_instance) which will produce a URI
+         for the controller namespace
+       - Break setup_components into two more parts: locate_components and
+         expand_component_module (rjbs)
+       - Allow Components to return anon classed from their COMPONENT method
+         correctly, and have action registration work on Controllers returned
+         as such by adding a catalyst_component_name accessor for all components
+         which returns the component instance's name to be used when building
+         actions etc.
+       - Adding X-Forwarded-Port to allow the frontend proxy to dictate the
+         frontend port (jshirley)
+       - Added Catalyst::Stats->created accessor for the time at the start of
+         the request.
 
   Documentation:
        - Fix POD to refer to ->config(key => $val), rather than
          ->config->{key} = $val, as the latter form is deprecated.
        - Clearer docs for the 'uri_for' method.
+       - Fix POD refering to CGI::Cookie. We're using CGI::Simple::Cookie.
+         (Forrest Cahoon)
 
 5.80007 2009-06-30 23:54:34
 
index 24b316c..d9fcc96 100644 (file)
@@ -1 +1 @@
-^(?!script/\w+\.pl$|TODO$|lib/.+(?<!ROADMAP)\.p(m|od)$|inc/|t/aggregate/.*\.t$|t/.*\.(gif|yml|pl|t)$|t/lib/.*\.pm$|t/something/(Makefile.PL|script/foo/bar/for_dist)$|t/conf/extra.conf.in$|Makefile.PL$|README$|MANIFEST$|Changes$|META.yml$)
+^(?!script/\w+\.pl$|TODO$|lib/.+(?<!ROADMAP)\.p(m|od)$|inc/|t/a(uthor|ggregate)/.*\.t$|t/.*\.(gif|yml|pl|t)$|t/lib/.*\.pm$|t/something/(Makefile.PL|script/foo/bar/for_dist)$|t/conf/extra.conf.in$|Makefile.PL$|README$|MANIFEST$|Changes$|META.yml$)
index 6e8fcc7..6fae99a 100644 (file)
@@ -1,17 +1,26 @@
+use strict;
+use warnings;
 use inc::Module::Install 0.87;
-
-perl_version '5.008001';
+BEGIN { # Make it easy for newbies
+    if ($Module::Install::AUTHOR) {
+        require Module::Install::AuthorRequires;
+        require Module::Install::CheckConflicts;
+        require Module::Install::AuthorTests;
+    }
+}
+perl_version '5.008004';
 
 name 'Catalyst-Runtime';
 all_from 'lib/Catalyst/Runtime.pm';
 
+requires 'List::MoreUtils';
 requires 'namespace::autoclean';
 requires 'namespace::clean';
 requires 'B::Hooks::EndOfScope' => '0.08';
 requires 'MooseX::Emulate::Class::Accessor::Fast' => '0.00801';
 requires 'Class::MOP' => '0.83';
 requires 'Moose' => '0.78';
-requires 'MooseX::MethodAttributes::Inheritable' => '0.14';
+requires 'MooseX::MethodAttributes::Inheritable' => '0.15';
 requires 'Carp';
 requires 'Class::C3::Adopt::NEXT' => '0.07';
 requires 'CGI::Simple::Cookie';
@@ -53,6 +62,7 @@ else {
         map  { glob } qw[t/*.t t/aggregate/*.t];
 }
 
+author_tests 't/author';
 author_requires(map {; $_ => 0 } qw(
   Test::NoTabs
   Test::Pod
@@ -111,7 +121,7 @@ my %conflicts = (
     'Catalyst::Plugin::Upload::Image::Magick' => '0.03',
     'Catalyst::Plugin::ConfigLoader'   => '0.22', # Older versions work but
                                                   # throw Data::Visitor warns
-    'Catalyst::Devel'                  => '0.09',
+    'Catalyst::Devel'                  => '1.19',
     'Catalyst::Plugin::SmartURI'       => '0.032',
     'CatalystX::CRUD'                  => '0.37',
     'Catalyst::Action::RenderView'     => '0.07',
@@ -122,6 +132,7 @@ my %conflicts = (
     'Catalyst::Action::REST'           => '0.67',
     'CatalystX::CRUD'                  => '0.42',
     'CatalystX::CRUD::Model::RDBO'     => '0.20',
+    'Catalyst::View::Mason'            => '0.17',
 );
 check_conflicts(%conflicts);
 
diff --git a/TODO b/TODO
index 2dd12f7..4a2b319 100644 (file)
--- a/TODO
+++ b/TODO
@@ -14,7 +14,7 @@
 # Compatibility warnings to add:
 
   - $self->config should warn as config should only ever be called as a
-    class method.
+    class method (TESTS).
 
 # Proposed functionality / feature additions:
 
@@ -40,7 +40,7 @@ http://github.com/willert/catalyst-plugin-log4perl-simple/tree
 ## App / ctx split:
 
   NOTE - these are notes that t0m thought up after doing back compat for
-         _component_class, may be inaccurate, wrong or missing things
+         catalyst_component_class, may be inaccurate, wrong or missing things
          bug mst (at least) to correct before trying more than the first 2
          steps. Please knock yourself out on the first two however :)
 
@@ -60,4 +60,3 @@ http://github.com/willert/catalyst-plugin-log4perl-simple/tree
   - Profit! (Things like changing the complete app config per vhost, i.e.
     writing a config loader / app class role which dispatches per vhost to
     differently configured apps is piss easy)
-
index 7556e34..f616ba8 100644 (file)
@@ -27,11 +27,12 @@ use URI::https;
 use Tree::Simple qw/use_weak_refs/;
 use Tree::Simple::Visitor::FindByUID;
 use Class::C3::Adopt::NEXT;
+use List::MoreUtils qw/uniq/;
 use attributes;
 use utf8;
 use Carp qw/croak carp shortmess/;
 
-BEGIN { require 5.008001; }
+BEGIN { require 5.008004; }
 
 has stack => (is => 'ro', default => sub { [] });
 has stash => (is => 'rw', default => sub { {} });
@@ -78,7 +79,7 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.80007';
+our $VERSION = '5.80011';
 
 {
     my $dev_version = $VERSION =~ /_\d{2}$/;
@@ -645,7 +646,7 @@ If you want to search for models, pass in a regexp as the argument.
 
 sub model {
     my ( $c, $name, @args ) = @_;
-
+    my $appclass = ref($c) || $c;
     if( $name ) {
         my @result = $c->_comp_search_prefixes( $name, qw/Model M/ );
         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
@@ -658,8 +659,8 @@ sub model {
         return $c->model( $c->stash->{current_model} )
           if $c->stash->{current_model};
     }
-    return $c->model( $c->config->{default_model} )
-      if $c->config->{default_model};
+    return $c->model( $appclass->config->{default_model} )
+      if $appclass->config->{default_model};
 
     my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/Model M/);
 
@@ -699,6 +700,7 @@ If you want to search for views, pass in a regexp as the argument.
 sub view {
     my ( $c, $name, @args ) = @_;
 
+    my $appclass = ref($c) || $c;
     if( $name ) {
         my @result = $c->_comp_search_prefixes( $name, qw/View V/ );
         return map { $c->_filter_component( $_, @args ) } @result if ref $name;
@@ -711,8 +713,8 @@ sub view {
         return $c->view( $c->stash->{current_view} )
           if $c->stash->{current_view};
     }
-    return $c->view( $c->config->{default_view} )
-      if $c->config->{default_view};
+    return $c->view( $appclass->config->{default_view} )
+      if $appclass->config->{default_view};
 
     my( $comp, $rest ) = $c->_comp_search_prefixes( undef, qw/View V/);
 
@@ -1174,7 +1176,7 @@ When used as a string, provides a textual URI.
 
 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
-relative to the application root (if it does). It is then merged with 
+relative to the application root (if it does). It is then merged with
 C<< $c->request->base >>; any C<@args> are appended as additional path
 components; and any C<%query_values> are appended as C<?foo=bar> parameters.
 
@@ -1186,13 +1188,13 @@ once the path is resolved, C<uri_for> continues as though a path was
 provided, appending any arguments or parameters and creating an absolute
 URI.
 
-The captures for the current request can be found in 
+The captures for the current request can be found in
 C<< $c->request->captures >>, and actions can be resolved using
 C<< Catalyst::Controller->action_for($name) >>. If you have a private action
 path, use C<< $c->uri_for_action >> instead.
 
   # Equivalent to $c->req->uri
-  $c->uri_for($c->action, $c->req->captures, 
+  $c->uri_for($c->action, $c->req->captures,
       @{ $c->req->args }, $c->req->params);
 
   # For the Foo action in the Bar controller
@@ -1206,6 +1208,12 @@ path, use C<< $c->uri_for_action >> instead.
 sub uri_for {
     my ( $c, $path, @args ) = @_;
 
+    if (blessed($path) && $path->isa('Catalyst::Controller')) {
+        $path = $path->path_prefix;
+        $path =~ s{/+\z}{};
+        $path .= '/';
+    }
+
     if ( blessed($path) ) { # action object
         my $captures = ( scalar @args && ref $args[0] eq 'ARRAY'
                          ? shift(@args)
@@ -1559,9 +1567,9 @@ sub execute {
 
 sub _stats_start_execute {
     my ( $c, $code ) = @_;
-
+    my $appclass = ref($c) || $c;
     return if ( ( $code->name =~ /^_.*/ )
-        && ( !$c->config->{show_internal_actions} ) );
+        && ( !$appclass->config->{show_internal_actions} ) );
 
     my $action_name = $code->reverse();
     $c->counter->{$action_name}++;
@@ -1875,7 +1883,7 @@ sub prepare {
         $c->prepare_read;
 
         # Parse the body unless the user wants it on-demand
-        unless ( $c->config->{parse_on_demand} ) {
+        unless ( ref($c)->config->{parse_on_demand} ) {
             $c->prepare_body;
         }
     }
@@ -2126,40 +2134,32 @@ sub setup_actions { my $c = shift; $c->dispatcher->setup_actions( $c, @_ ) }
 
 =head2 $c->setup_components
 
-Sets up components. Specify a C<setup_components> config option to pass
-additional options directly to L<Module::Pluggable>. To add additional
-search paths, specify a key named C<search_extra> as an array
-reference. Items in the array beginning with C<::> will have the
-application class name prepended to them.
+This method is called internally to set up the application's components.
 
-All components found will also have any
-L<inner packages|Devel::InnerPackage> loaded and set up as components.
-Note, that modules which are B<not> an I<inner package> of the main
-file namespace loaded will not be instantiated as components.
+It finds modules by calling the L<locate_components> method, expands them to
+package names with the L<expand_component_module> method, and then installs
+each component into the application.
+
+The C<setup_components> config option is passed to both of the above methods.
+
+Installation of each component is performed by the L<setup_component> method,
+below.
 
 =cut
 
 sub setup_components {
     my $class = shift;
 
-    my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
     my $config  = $class->config->{ setup_components };
-    my $extra   = delete $config->{ search_extra } || [];
 
-    push @paths, @$extra;
-
-    my $locator = Module::Pluggable::Object->new(
-        search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
-        %$config
-    );
-
-    my @comps = sort { length $a <=> length $b } $locator->plugins;
+    my @comps = sort { length $a <=> length $b }
+                $class->locate_components($config);
     my %comps = map { $_ => 1 } @comps;
 
-    my $deprecated_component_names = grep { /::[CMV]::/ } @comps;
+    my $deprecatedcatalyst_component_names = grep { /::[CMV]::/ } @comps;
     $class->log->warn(qq{Your application is using the deprecated ::[MVC]:: type naming scheme.\n}.
         qq{Please switch your class names to ::Model::, ::View:: and ::Controller: as appropriate.\n}
-    ) if $deprecated_component_names;
+    ) if $deprecatedcatalyst_component_names;
 
     for my $component ( @comps ) {
 
@@ -2168,30 +2168,76 @@ sub setup_components {
         # we know M::P::O found a file on disk so this is safe
 
         Catalyst::Utils::ensure_class_loaded( $component, { ignore_loaded => 1 } );
-        #Class::MOP::load_class($component);
-
-        my $module  = $class->setup_component( $component );
-        my %modules = (
-            $component => $module,
-            map {
-                $_ => $class->setup_component( $_ )
-            } grep {
-              not exists $comps{$_}
-            } Devel::InnerPackage::list_packages( $component )
-        );
 
-        for my $key ( keys %modules ) {
-            $class->components->{ $key } = $modules{ $key };
+        # Needs to be done as soon as the component is loaded, as loading a sub-component
+        # (next time round the loop) can cause us to get the wrong metaclass..
+        $class->_controller_init_base_classes($component);
+    }
+
+    for my $component (@comps) {
+        $class->components->{ $component } = $class->setup_component($component);
+        for my $component ($class->expand_component_module( $component, $config )) {
+            next if $comps{$component};
+            $class->_controller_init_base_classes($component); # Also cover inner packages
+            $class->components->{ $component } = $class->setup_component($component);
         }
     }
 }
 
+=head2 $c->locate_components( $setup_component_config )
+
+This method is meant to provide a list of component modules that should be
+setup for the application.  By default, it will use L<Module::Pluggable>.
+
+Specify a C<setup_components> config option to pass additional options directly
+to L<Module::Pluggable>. To add additional search paths, specify a key named
+C<search_extra> as an array reference. Items in the array beginning with C<::>
+will have the application class name prepended to them.
+
+=cut
+
+sub locate_components {
+    my $class  = shift;
+    my $config = shift;
+
+    my @paths   = qw( ::Controller ::C ::Model ::M ::View ::V );
+    my $extra   = delete $config->{ search_extra } || [];
+
+    push @paths, @$extra;
+
+    my $locator = Module::Pluggable::Object->new(
+        search_path => [ map { s/^(?=::)/$class/; $_; } @paths ],
+        %$config
+    );
+
+    my @comps = $locator->plugins;
+
+    return @comps;
+}
+
+=head2 $c->expand_component_module( $component, $setup_component_config )
+
+Components found by C<locate_components> will be passed to this method, which
+is expected to return a list of component (package) names to be set up.
+
+=cut
+
+sub expand_component_module {
+    my ($class, $module) = @_;
+    return Devel::InnerPackage::list_packages( $module );
+}
+
 =head2 $c->setup_component
 
 =cut
 
+# FIXME - Ugly, ugly hack to ensure the we force initialize non-moose base classes
+#         nearest to Catalyst::Controller first, no matter what order stuff happens
+#         to be loaded. There are TODO tests in Moose for this, see
+#         f2391d17574eff81d911b97be15ea51080500003
 sub _controller_init_base_classes {
     my ($app_class, $component) = @_;
+    return unless $component->isa('Catalyst::Controller');
     foreach my $class ( reverse @{ mro::get_linear_isa($component) } ) {
         Moose::Meta::Class->initialize( $class )
             unless find_meta($class);
@@ -2205,20 +2251,12 @@ sub setup_component {
         return $component;
     }
 
-    # FIXME - Ugly, ugly hack to ensure the we force initialize non-moose base classes
-    #         nearest to Catalyst::Controller first, no matter what order stuff happens
-    #         to be loaded. There are TODO tests in Moose for this, see
-    #         f2391d17574eff81d911b97be15ea51080500003
-    if ($component->isa('Catalyst::Controller')) {
-        $class->_controller_init_base_classes($component);
-    }
-
     my $suffix = Catalyst::Utils::class2classsuffix( $component );
     my $config = $class->config->{ $suffix } || {};
-    # Stash _component_name in the config here, so that custom COMPONENT
+    # Stash catalyst_component_name in the config here, so that custom COMPONENT
     # methods also pass it. local to avoid pointlessly shitting in config
     # for the debug screen, as $component is already the key name.
-    local $config->{_component_name} = $component;
+    local $config->{catalyst_component_name} = $component;
 
     my $instance = eval { $component->COMPONENT( $class, $config ); };
 
@@ -2638,6 +2676,18 @@ changes are made to the request.
     The host value for $c->req->base and $c->req->uri is set to the real
     host, as read from the HTTP X-Forwarded-Host header.
 
+Additionally, you may be running your backend application on an insecure
+connection (port 80) while your frontend proxy is running under SSL.  If there
+is a discrepancy in the ports, use the HTTP header C<X-Forwarded-Port> to
+tell Catalyst what port the frontend listens on.  This will allow all URIs to
+be created properly.
+
+In the case of passing in:
+
+    X-Forwarded-Port: 443
+
+All calls to C<uri_for> will result in an https link, as is expected.
+
 Obviously, your web server must support these headers for this to work.
 
 In a more complex server farm environment where you may have your
@@ -2710,7 +2760,7 @@ acme: Leon Brocard <leon@astray.com>
 
 Andrew Bramble
 
-Andrew Ford
+Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
 
 Andrew Ruthven
 
@@ -2726,6 +2776,14 @@ chansen: Christian Hansen
 
 chicks: Christopher Hicks
 
+Chisel Wright C<pause@herlpacker.co.uk>
+
+Danijel Milicevic C<me@danijel.de>
+
+David Kamholz E<lt>dkamholz@cpan.orgE<gt>
+
+David Naughton, C<naughton@umn.edu>
+
 David E. Wheeler
 
 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
@@ -2738,10 +2796,14 @@ esskar: Sascha Kiefer
 
 fireartist: Carl Franks <cfranks@cpan.org>
 
+frew: Arthur Axel "fREW" Schmidt <frioux@gmail.com>
+
 gabb: Danijel Milicevic
 
 Gary Ashton Jones
 
+Gavin Henry C<ghenry@perl.me.uk>
+
 Geoff Richards
 
 hobbs: Andrew Rodland <andrew@cleverdomain.org>
@@ -2750,7 +2812,7 @@ ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
 
 jcamacho: Juan Camacho
 
-jester: Jesse Sheidlower
+jester: Jesse Sheidlower C<jester@panix.com>
 
 jhannah: Jay Hannah <jay@jays.net>
 
@@ -2760,6 +2822,10 @@ Johan Lindstrom
 
 jon: Jon Schutz <jjschutz@cpan.org>
 
+Jonathan Rockway C<< <jrockway@cpan.org> >>
+
+Kieren Diment C<kd@totaldatasolution.com>
+
 konobi: Scott McWhirter <konobi@cpan.org>
 
 marcus: Marcus Ramberg <mramberg@cpan.org>
@@ -2790,14 +2856,22 @@ rafl: Florian Ragwitz <rafl@debian.org>
 
 random: Roland Lammel <lammel@cpan.org>
 
+Robert Sedlacek C<< <rs@474.at> >>
+
 sky: Arthur Bergman
 
 t0m: Tomas Doran <bobtfish@bobtfish.net>
 
 Ulf Edvinsson
 
+Viljo Marrandi C<vilts@yahoo.com>
+
+Will Hawes C<info@whawes.co.uk>
+
 willert: Sebastian Willert <willert@cpan.org>
 
+Yuval Kogman, C<nothingmuch@woobling.org>
+
 =head1 LICENSE
 
 This library is free software. You can redistribute it and/or modify it under
index af65452..87b37fd 100644 (file)
@@ -104,7 +104,7 @@ and so on. This determines how the action is dispatched to.
 =head2 class
 
 Returns the name of the component where this action is defined.
-Derived by calling the L<Catalyst::Component/_component_name|_component_name>
+Derived by calling the L<Catalyst::Component/catalyst_component_name|catalyst_component_name>
 method on each component.
 
 =head2 code
index f252f05..9942840 100644 (file)
@@ -6,7 +6,7 @@ use Class::MOP;
 use Moose::Util ();
 
 sub mk_classdata {
-  my ($class, $attribute) = @_;
+  my ($class, $attribute, $warn_on_instance) = @_;
   confess("mk_classdata() is a class method, not an object method")
     if blessed $class;
 
index ee1f99a..fe0ef6f 100644 (file)
@@ -60,13 +60,16 @@ component loader with config() support and a process() method placeholder.
 __PACKAGE__->mk_classdata('_plugins');
 __PACKAGE__->mk_classdata('_config');
 
-has _component_name => ( is => 'ro' ); # Cannot be required => 1 as context
+has catalyst_component_name => ( is => 'ro' ); # Cannot be required => 1 as context
                                        # class @ISA component - HATE
 # Make accessor callable as a class method, as we need to call setup_actions
 # on the application class, which we don't have an instance of, ewwwww
-around _component_name => sub {
+# Also, naughty modules like Catalyst::View::JSON try to write to _everything_,
+# so spit a warning, ignore that (and try to do the right thing anyway) here..
+around catalyst_component_name => sub {
     my ($orig, $self) = (shift, shift);
-    blessed($self) ? $self->$orig(@_) : $self;
+    Carp::cluck("Tried to write to the catalyst_component_name accessor - is your component broken or just mad? (Write ignored - using default value.)") if scalar @_;
+    blessed($self) ? $self->$orig() || blessed($self) : $self;
 };
 
 sub BUILDARGS {
@@ -110,6 +113,8 @@ sub COMPONENT {
 
 sub config {
     my $self = shift;
+    # Uncomment once sane to do so
+    #Carp::cluck("config method called on instance") if ref $self;
     my $config = $self->_config || {};
     if (@_) {
         my $newconfig = { %{@_ > 1 ? {@_} : $_[0]} };
index 3f79106..1d91b3c 100644 (file)
@@ -2,7 +2,7 @@ package Catalyst::Controller;
 
 use Moose;
 use Moose::Util qw/find_meta/;
-
+use List::MoreUtils qw/uniq/;
 use namespace::clean -except => 'meta';
 
 BEGIN { extends qw/Catalyst::Component MooseX::MethodAttributes::Inheritable/; }
@@ -29,9 +29,9 @@ has action_namespace =>
      predicate => 'has_action_namespace',
     );
 
-has _controller_actions =>
+has actions =>
     (
-     is => 'rw',
+     accessor => '_controller_actions',
      isa => 'HashRef',
      init_arg => undef,
     );
@@ -44,6 +44,8 @@ sub BUILD {
     $self->_controller_actions($attr_value);
 }
 
+
+
 =head1 NAME
 
 Catalyst::Controller - Catalyst Controller base class
@@ -135,28 +137,30 @@ around action_namespace => sub {
     my $orig = shift;
     my ( $self, $c ) = @_;
 
+    my $class = ref($self) || $self;
+    my $appclass = ref($c) || $c;
     if( ref($self) ){
         return $self->$orig if $self->has_action_namespace;
     } else {
-        return $self->config->{namespace} if exists $self->config->{namespace};
+        return $class->config->{namespace} if exists $class->config->{namespace};
     }
 
     my $case_s;
     if( $c ){
-        $case_s = $c->config->{case_sensitive};
+        $case_s = $appclass->config->{case_sensitive};
     } else {
         if ($self->isa('Catalyst')) {
-            $case_s = $self->config->{case_sensitive};
+            $case_s = $class->config->{case_sensitive};
         } else {
             if (ref $self) {
-                $case_s = $self->_application->config->{case_sensitive};
+                $case_s = ref($self->_application)->config->{case_sensitive};
             } else {
                 confess("Can't figure out case_sensitive setting");
             }
         }
     }
 
-    my $namespace = Catalyst::Utils::class2prefix($self->_component_name, $case_s) || '';
+    my $namespace = Catalyst::Utils::class2prefix($self->catalyst_component_name, $case_s) || '';
     $self->$orig($namespace) if ref($self);
     return $namespace;
 };
@@ -177,8 +181,8 @@ around path_prefix => sub {
 
 sub get_action_methods {
     my $self = shift;
-    my $meta = find_meta($self);
-    confess("Metaclass for "
+    my $meta = find_meta($self) || confess("No metaclass setup for $self");
+    confess("Metaclass "
           . ref($meta) . " for "
           . $meta->name
           . " cannot support register_actions." )
@@ -196,7 +200,7 @@ sub get_action_methods {
                   . ( ref $self ) )
           } keys %{ $self->_controller_actions }
     ) if ( ref $self );
-    return @methods;
+    return uniq @methods;
 }
 
 
@@ -207,7 +211,7 @@ sub register_actions {
 
 sub register_action_methods {
     my ( $self, $c, @methods ) = @_;
-    my $class = $self->_component_name;
+    my $class = $self->catalyst_component_name;
     #this is still not correct for some reason.
     my $namespace = $self->action_namespace($c);
 
index 890961d..3654a11 100644 (file)
@@ -80,14 +80,16 @@ sub list {
 
     return unless $self->_endpoints;
 
-    my $column_width = Catalyst::Utils::term_width() - 35 - 9;
+    my $avail_width = Catalyst::Utils::term_width() - 9;
+    my $col1_width = ($avail_width * .50) < 35 ? 35 : int($avail_width * .50);
+    my $col2_width = $avail_width - $col1_width;
     my $paths = Text::SimpleTable->new(
-       [ 35, 'Path Spec' ], [ $column_width, 'Private' ],
+        [ $col1_width, 'Path Spec' ], [ $col2_width, 'Private' ],
     );
 
     my $has_unattached_actions;
     my $unattached_actions = Text::SimpleTable->new(
-        [ 35, 'Private' ], [ $column_width, 'Missing parent' ],
+        [ $col1_width, 'Private' ], [ $col2_width, 'Missing parent' ],
     );
 
     ENDPOINT: foreach my $endpoint (
index 95367ac..545e607 100644 (file)
@@ -47,9 +47,11 @@ Debug output for Path dispatch points
 
 sub list {
     my ( $self, $c ) = @_;
-    my $column_width = Catalyst::Utils::term_width() - 35 - 9;
+    my $avail_width = Catalyst::Utils::term_width() - 9;
+    my $col1_width = ($avail_width * .50) < 35 ? 35 : int($avail_width * .50);
+    my $col2_width = $avail_width - $col1_width;
     my $paths = Text::SimpleTable->new(
-       [ 35, 'Path' ], [ $column_width, 'Private' ]
+       [ $col1_width, 'Path' ], [ $col2_width, 'Private' ]
     );
     foreach my $path ( sort keys %{ $self->_paths } ) {
         my $display_path = $path eq '/' ? $path : "/$path";
index 11a9cbf..0d6da04 100644 (file)
@@ -47,8 +47,12 @@ Output a table of all regex actions, and their private equivalent.
 
 sub list {
     my ( $self, $c ) = @_;
-    my $column_width = Catalyst::Utils::term_width() - 35 - 9;
-    my $re = Text::SimpleTable->new( [ 35, 'Regex' ], [ $column_width, 'Private' ] );
+    my $avail_width = Catalyst::Utils::term_width() - 9;
+    my $col1_width = ($avail_width * .50) < 35 ? 35 : int($avail_width * .50);
+    my $col2_width = $avail_width - $col1_width;
+    my $re = Text::SimpleTable->new(
+        [ $col1_width, 'Regex' ], [ $col2_width, 'Private' ]
+    );
     for my $regex ( @{ $self->_compiled } ) {
         my $action = $regex->{action};
         $re->row( $regex->{path}, "/$action" );
index e90cdc1..3d6573b 100644 (file)
@@ -335,7 +335,7 @@ sub _invoke_as_component {
                 reverse   => "$component_class->$method",
                 class     => $component_class,
                 namespace => Catalyst::Utils::class2prefix(
-                    $component_class, $c->config->{case_sensitive}
+                    $component_class, ref($c)->config->{case_sensitive}
                 ),
             }
         );
@@ -615,9 +615,12 @@ sub setup_actions {
 sub _display_action_tables {
     my ($self, $c) = @_;
 
-    my $column_width = Catalyst::Utils::term_width() - 20 - 36 - 12;
+    my $avail_width = Catalyst::Utils::term_width() - 12;
+    my $col1_width = ($avail_width * .25) < 20 ? 20 : int($avail_width * .25);
+    my $col2_width = ($avail_width * .50) < 36 ? 36 : int($avail_width * .50);
+    my $col3_width =  $avail_width - $col1_width - $col2_width;
     my $privates = Text::SimpleTable->new(
-        [ 20, 'Private' ], [ 36, 'Class' ], [ $column_width, 'Method' ]
+        [ $col1_width, 'Private' ], [ $col2_width, 'Class' ], [ $col3_width, 'Method' ]
     );
 
     my $has_private = 0;
index b9ec98a..443975e 100644 (file)
@@ -48,10 +48,12 @@ sub finalize_body {
     my $body = $c->response->body;
     no warnings 'uninitialized';
     if ( blessed($body) && $body->can('read') or ref($body) eq 'GLOB' ) {
-        while ( !eof $body ) {
-            read $body, my ($buffer), $CHUNKSIZE;
-            last unless $self->write( $c, $buffer );
-        }
+        my $got;
+        do {
+            $got = read $body, my ($buffer), $CHUNKSIZE;
+            $got = 0 unless $self->write( $c, $buffer );
+        } while $got > 0;
+
         close $body;
     }
     else {
@@ -110,7 +112,7 @@ sub finalize_error {
     my ( $self, $c ) = @_;
 
     $c->res->content_type('text/html; charset=utf-8');
-    my $name = $c->config->{name} || join(' ', split('::', ref $c));
+    my $name = ref($c)->config->{name} || join(' ', split('::', ref $c));
 
     my ( $title, $error, $infos );
     if ( $c->debug ) {
@@ -315,13 +317,14 @@ sets up the L<Catalyst::Request> object body using L<HTTP::Body>
 sub prepare_body {
     my ( $self, $c ) = @_;
 
+    my $appclass = ref($c) || $c;
     if ( my $length = $self->read_length ) {
         my $request = $c->request;
         unless ( $request->_body ) {
             my $type = $request->header('Content-Type');
             $request->_body(HTTP::Body->new( $type, $length ));
-            $request->_body->tmpdir( $c->config->{uploadtmp} )
-              if exists $c->config->{uploadtmp};
+            $request->_body->tmpdir( $appclass->config->{uploadtmp} )
+              if exists $appclass->config->{uploadtmp};
         }
 
         while ( my $buffer = $self->read($c) ) {
index 48dc201..8416e09 100644 (file)
@@ -57,9 +57,9 @@ sub prepare_connection {
 
   PROXY_CHECK:
     {
-        unless ( $c->config->{using_frontend_proxy} ) {
+        unless ( ref($c)->config->{using_frontend_proxy} ) {
             last PROXY_CHECK if $ENV{REMOTE_ADDR} ne '127.0.0.1';
-            last PROXY_CHECK if $c->config->{ignore_frontend_proxy};
+            last PROXY_CHECK if ref($c)->config->{ignore_frontend_proxy};
         }
         last PROXY_CHECK unless $ENV{HTTP_X_FORWARDED_FOR};
 
@@ -67,6 +67,9 @@ sub prepare_connection {
         # as 127.0.0.1. Select the most recent upstream IP (last in the list)
         my ($ip) = $ENV{HTTP_X_FORWARDED_FOR} =~ /([^,\s]+)$/;
         $request->address($ip);
+        if ( defined $ENV{HTTP_X_FORWARDED_PORT} ) {
+            $ENV{SERVER_PORT} = $ENV{HTTP_X_FORWARDED_PORT};
+        }
     }
 
     $request->hostname( $ENV{REMOTE_HOST} ) if exists $ENV{REMOTE_HOST};
@@ -123,9 +126,9 @@ sub prepare_path {
     # If we are running as a backend proxy, get the true hostname
   PROXY_CHECK:
     {
-        unless ( $c->config->{using_frontend_proxy} ) {
+        unless ( ref($c)->config->{using_frontend_proxy} ) {
             last PROXY_CHECK if $host !~ /localhost|127.0.0.1/;
-            last PROXY_CHECK if $c->config->{ignore_frontend_proxy};
+            last PROXY_CHECK if ref($c)->config->{ignore_frontend_proxy};
         }
         last PROXY_CHECK unless $ENV{HTTP_X_FORWARDED_HOST};
 
@@ -134,6 +137,9 @@ sub prepare_path {
         # backend could be on any port, so
         # assume frontend is on the default port
         $port = $c->request->secure ? 443 : 80;
+        if ( $ENV{HTTP_X_FORWARDED_PORT} ) {
+            $port = $ENV{HTTP_X_FORWARDED_PORT};
+        }
     }
 
     # set the request URI
index 9626f66..62c5d0b 100644 (file)
@@ -12,10 +12,6 @@ use Socket;
 use IO::Socket::INET ();
 use IO::Select       ();
 
-# For PAR
-require Catalyst::Engine::HTTP::Restarter;
-require Catalyst::Engine::HTTP::Restarter::Watcher;
-
 use constant CHUNKSIZE => 64 * 1024;
 use constant DEBUG     => $ENV{CATALYST_HTTP_DEBUG} || 0;
 
@@ -159,7 +155,7 @@ around write => sub {
     # Prepend the headers if they have not yet been sent
     if ( $self->_has_header_buf ) {
         $self->_warn_on_write_error(
-            $self->$orig($self->_clear_header_buf)
+            $self->$orig($c, $self->_clear_header_buf)
         );
     }
 
@@ -368,6 +364,9 @@ sub _handler {
     while (1) {
         my ( $path, $query_string ) = split /\?/, $uri, 2;
 
+        # URI is not the same as path. Remove scheme, domain name and port from it
+        $path =~ s{^https?://[^/?#]+}{};
+
         # Initialize CGI environment
         local %ENV = (
             PATH_INFO       => $path         || '',
index 4a40516..3383fc6 100644 (file)
@@ -237,8 +237,9 @@ C<http://localhost:3000/some/path> then C<base> is C<http://localhost:3000/>.
 
 =head2 $req->body
 
-Returns the message body of the request, unless Content-Type is
-C<application/x-www-form-urlencoded> or C<multipart/form-data>.
+Returns the message body of the request, as returned by L<HTTP::Body>: a string,
+unless Content-Type is C<application/x-www-form-urlencoded>, C<text/xml>, or
+C<multipart/form-data>, in which case a L<File::Temp> object is returned.
 
 =head2 $req->body_parameters
 
@@ -300,7 +301,7 @@ Returns a reference to a hash containing the cookies.
 
     print $c->request->cookies->{mycookie}->value;
 
-The cookies in the hash are indexed by name, and the values are L<CGI::Cookie>
+The cookies in the hash are indexed by name, and the values are L<CGI::Simple::Cookie>
 objects.
 
 =head2 $req->header
index 595decb..cb73a34 100644 (file)
@@ -102,11 +102,11 @@ it found, while L<Catalyst::View::TT> defaults to C<text/html>.
 
 Returns a reference to a hash containing cookies to be set. The keys of the
 hash are the cookies' names, and their corresponding values are hash
-references used to construct a L<CGI::Cookie> object.
+references used to construct a L<CGI::Simple::Cookie> object.
 
     $c->response->cookies->{foo} = { value => '123' };
 
-The keys of the hash reference on the right correspond to the L<CGI::Cookie>
+The keys of the hash reference on the right correspond to the L<CGI::Simple::Cookie>
 parameters of the same name, except they are used without a leading dash.
 Possible parameters are:
 
index 271d7a5..d94f3f0 100644 (file)
@@ -3,11 +3,11 @@ package Catalyst::Runtime;
 use strict;
 use warnings;
 
-BEGIN { require 5.008001; }
+BEGIN { require 5.008004; }
 
 # Remember to update this in Catalyst as well!
 
-our $VERSION='5.80007';
+our $VERSION='5.80011';
 
 $VERSION = eval $VERSION;
 
index 46b5ed4..fd6ec8c 100644 (file)
@@ -84,6 +84,10 @@ sub profile {
     return $node->getUID;
 }
 
+sub created {
+    return @{ shift->{tree}->getNodeValue->{t} };
+}
+
 sub elapsed {
     return tv_interval(shift->{tree}->getNodeValue->{t});
 }
@@ -297,6 +301,13 @@ The profiling point will be ignored if the UID has not been previously defined.
 Returns the UID of the current point in the profile tree.  The UID is
 automatically assigned if not explicitly given.
 
+=head2 created
+
+    ($seconds, $microseconds) = $stats->created;
+
+Returns the time the object was created, in C<gettimeofday> format, with
+Unix epoch seconds followed by microseconds.
+
 =head2 elapsed
 
     $elapsed = $stats->elapsed
index e10d6d2..ea5d2c3 100644 (file)
@@ -10,10 +10,13 @@ our $iters;
 
 BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
 
-use Test::More tests => 6*$iters;
-
+use Test::More;
 use Catalyst::Test 'TestAppIndexDefault';
 
+plan 'skip_all' if ( $ENV{CATALYST_SERVER} );
+
+plan tests => 6*$iters;
+
 if ( $ENV{CAT_BENCHMARK} ) {
     require Benchmark;
     Benchmark::timethis( $iters, \&run_tests );
index 34ad404..beced91 100644 (file)
@@ -10,9 +10,13 @@ our $iters;
 
 BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
 
-use Test::More tests => 3*$iters;
+use Test::More;
 use Catalyst::Test 'TestAppMatchSingleArg';
 
+plan 'skip_all' if ( $ENV{CATALYST_SERVER} );
+
+plan tests => 3*$iters;
+
 if ( $ENV{CAT_BENCHMARK} ) {
     require Benchmark;
     Benchmark::timethis( $iters, \&run_tests );
index 2697940..36a679e 100644 (file)
@@ -131,8 +131,10 @@ sub run_tests {
             'TestApp::Controller::Action::Regexp',
             'Test Class'
         );
+        my $location = $response->header('location');
+        $location =~ s/localhost(:\d+)?/localhost/;
         is(
-            $response->header('location'),
+            $location,
             $url,
             'Redirect URI is the same as the request URI'
         );
index 156956b..4300744 100644 (file)
@@ -10,7 +10,7 @@ our $iters;
 
 BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
 
-use Test::More tests => 10*$iters;
+use Test::More tests => 15*$iters;
 use Catalyst::Test 'TestApp';
 
 if ( $ENV{CAT_BENCHMARK} ) {
@@ -69,4 +69,14 @@ EOF
         is( $response->content_length, -s $file, 'Response Content-Length' );
         is( $response->content, $buffer, 'Content is read from filehandle' );
     }
+
+    {
+        my $size = 128 * 1024; # more than one read with the default chunksize
+
+        ok( my $response = request('http://localhost/action/streaming/body_large'), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content_length, $size, 'Response Content-Length' );
+        is( $response->content, "\0" x $size, 'Content is read from filehandle' );
+    }
 }
index 73d3f9c..d7a9a2c 100644 (file)
@@ -11,13 +11,13 @@ use Catalyst::Test 'TestApp';
     my $response = request('http://localhost/anon/test');
     ok($response->is_success);
     is($response->header('X-Component-Name-Action'),
-        'TestApp::Controller::Anon', 'Action can see correct _component_name');
+        'TestApp::Controller::Anon', 'Action can see correct catalyst_component_name');
     isnt($response->header('X-Component-Instance-Name-Action'),
-        'TestApp::Controller::Anon', 'ref($controller) ne _component_name');
+        'TestApp::Controller::Anon', 'ref($controller) ne catalyst_component_name');
     is($response->header('X-Component-Name-Controller'),
-        'TestApp::Controller::Anon', 'Controller can see correct _component_name');
+        'TestApp::Controller::Anon', 'Controller can see correct catalyst_component_name');
     is($response->header('X-Class-In-Action'),
-        'TestApp::Controller::Anon', '$action->class is _component_name');
+        'TestApp::Controller::Anon', '$action->class is catalyst_component_name');
     is($response->header('X-Anon-Trait-Applied'),
         '1', 'Anon controller class has trait applied correctly');
 }
index 9396ffb..15924cd 100644 (file)
@@ -10,9 +10,13 @@ our $iters;
 
 BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
 
-use Test::More tests => 3*$iters;
+use Test::More;
 use Catalyst::Test 'TestAppOneView';
 
+plan 'skip_all' if ( $ENV{CATALYST_SERVER} );
+
+plan tests => 3*$iters;
+
 if ( $ENV{CAT_BENCHMARK} ) {
     require Benchmark;
     Benchmark::timethis( $iters, \&run_tests );
index 551561e..d0ef1f0 100644 (file)
@@ -6,7 +6,7 @@ use warnings;
 use FindBin;
 use lib "$FindBin::Bin/../lib";
 
-use Test::More tests => 17;
+use Test::More tests => 18;
 use Catalyst::Test 'TestApp';
 
 use Catalyst::Request;
@@ -22,6 +22,7 @@ use HTTP::Request::Common;
         'X-Multiple'       => [ 1 .. 5 ],
         'X-Forwarded-Host' => 'frontend.server.com',
         'X-Forwarded-For'  => '192.168.1.1, 1.2.3.4',
+        'X-Forwarded-Port' => 443
     );
  
     ok( my $response = request($request), 'Request' );
@@ -30,6 +31,7 @@ use HTTP::Request::Common;
     like( $response->content, qr/^bless\( .* 'Catalyst::Request' \)$/s, 'Content is a serialized Catalyst::Request' );
     ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
     isa_ok( $creq, 'Catalyst::Request' );
+    ok( $creq->secure, 'Forwarded port sets securet' );
     isa_ok( $creq->headers, 'HTTP::Headers', 'Catalyst::Request->headers' );
     is( $creq->header('X-Whats-Cool'), $request->header('X-Whats-Cool'), 'Catalyst::Request->header X-Whats-Cool' );
     
index 10b071b..7e5cba2 100644 (file)
@@ -37,6 +37,11 @@ use HTTP::Request::Common;
     }
 
     isa_ok( $creq, 'Catalyst::Request' );
-    
-    is( $creq->remote_user, 'dwc', '$c->req->remote_user ok' );
+    SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} ) {
+            skip 'Using remote server', 1;
+        }
+        is( $creq->remote_user, 'dwc', '$c->req->remote_user ok' );
+    }
 }
index b8f3944..4431f5a 100644 (file)
@@ -8,7 +8,7 @@ use lib "$FindBin::Bin/../lib";
 
 use Test::More;
 
-plan tests => 29;
+plan tests => 30;
 
 use_ok('TestApp');
 
@@ -97,6 +97,10 @@ my $context = TestApp->new( {
                 namespace => 'yada',
               } );
 
+is($context->uri_for($context->controller('Action')),
+   "http://127.0.0.1/foo/yada/action/",
+   "uri_for a controller");
+
 is($context->uri_for($path_action),
    "http://127.0.0.1/foo/action/relative/relative",
    "uri_for correct for path action");
similarity index 61%
rename from t/optional_http-server.t
rename to t/author/optional_http-server.t
index 60f9259..d4a2183 100644 (file)
@@ -1,26 +1,20 @@
 use strict;
 use warnings;
 
-use Test::More;
-BEGIN {
-    plan skip_all => 'set TEST_HTTP to enable this test' unless $ENV{TEST_HTTP};
-}
+use Test::More tests => 1;
 
 use File::Path;
 use FindBin;
 use IPC::Open3;
 use IO::Socket;
 
-eval "use Catalyst::Devel 1.0";
-plan skip_all => 'Catalyst::Devel required' if $@;
-eval "use File::Copy::Recursive";
-plan skip_all => 'File::Copy::Recursive required' if $@;
-plan tests => 1;
+use Catalyst::Devel 1.0;
+use File::Copy::Recursive;
 
 # Run a single test by providing it as the first arg
 my $single_test = shift;
 
-my $tmpdir = "$FindBin::Bin/../t/tmp";
+my $tmpdir = "$FindBin::Bin/../../t/tmp";
 
 # clean up
 rmtree $tmpdir if -d $tmpdir;
@@ -28,24 +22,28 @@ rmtree $tmpdir if -d $tmpdir;
 # create a TestApp and copy the test libs into it
 mkdir $tmpdir;
 chdir $tmpdir;
-system( $^X, "-I$FindBin::Bin/../lib", "$FindBin::Bin/../script/catalyst.pl", 'TestApp' );
+system( $^X, "-I$FindBin::Bin/../../lib", "$FindBin::Bin/../../script/catalyst.pl", 'TestApp' );
 chdir "$FindBin::Bin/..";
-File::Copy::Recursive::dircopy( 't/lib', 't/tmp/TestApp/lib' );
+File::Copy::Recursive::dircopy( '../t/lib', '../t/tmp/TestApp/lib' ) or die;
 
 # remove TestApp's tests
-rmtree 't/tmp/TestApp/t';
+rmtree '../t/tmp/TestApp/t' or die;
 
 # spawn the standalone HTTP server
 my $port = 30000 + int rand(1 + 10000);
-my $pid = open3( undef, my $server, undef,
-  $^X, "-I$FindBin::Bin/../lib",
-  "$FindBin::Bin/../t/tmp/TestApp/script/testapp_server.pl", '-port', $port )
+my @cmd = ($^X, "-I$FindBin::Bin/../../lib",
+  "$FindBin::Bin/../../t/tmp/TestApp/script/testapp_server.pl", '-port', $port );
+my $pid = open3( undef, my $server, undef, @cmd)
     or die "Unable to spawn standalone HTTP server: $!";
 
 # wait for it to start
 print "Waiting for server to start...\n";
+my $timeout = 30;
+my $count = 0;
 while ( check_port( 'localhost', $port ) != 1 ) {
     sleep 1;
+    die("Server did not start within $timeout seconds: " . join(' ', @cmd))
+        if $count++ > $timeout;
 }
 
 # run the testsuite against the HTTP server
@@ -53,10 +51,10 @@ $ENV{CATALYST_SERVER} = "http://localhost:$port";
 
 my $return;
 if ( $single_test ) {
-    $return = system( "$^X -Ilib/ $single_test" );
+    $return = system( "$^X -I../lib/ $single_test" );
 }
 else {
-    $return = prove( '-r', '-Ilib/', glob('t/aggregate/live_*.t') );
+    $return = prove( '-r', '-I../lib/', glob('../t/aggregate/live_*.t') );
 }
 
 # shut it down
@@ -64,7 +62,7 @@ kill 'INT', $pid;
 close $server;
 
 # clean up
-rmtree "$FindBin::Bin/../t/tmp" if -d "$FindBin::Bin/../t/tmp";
+rmtree "$FindBin::Bin/../../t/tmp" if -d "$FindBin::Bin/../../t/tmp";
 
 is( $return, 0, 'live tests' );
 
index d8c67c2..27d8fa9 100644 (file)
@@ -12,7 +12,6 @@ my @modules = qw/
     Catalyst::Component
     Catalyst::Dispatcher
     Catalyst::DispatchType
-    Catalyst::Engine::HTTP::Restarter::Watcher
     Catalyst::Engine
     Catalyst::Log
     Catalyst::Request::Upload
diff --git a/t/cdi_backcompat_plugin_accessor_override.t b/t/cdi_backcompat_plugin_accessor_override.t
deleted file mode 100644 (file)
index d3efa18..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-use strict;
-use warnings;
-use lib 't/lib';
-
-use Test::More tests => 2;
-use Test::Exception;
-
-# Force a stack trace.
-use Carp;
-$SIG{__DIE__} = \&Carp::confess;
-
-{
-    package CDICompatTestApp;
-    use Catalyst qw/
-           +CDICompatTestPlugin
-    /;
-    # Calling ->config here (before we call setup). With CDI/Cat 5.70 this
-    # causes *CDICompatTestApp::_config to have a class data accessor created.
-    
-    # If this doesn't happen, then later when we've added CDICompatTestPlugin
-    # to @ISA, we fail in the overridden ->setup method when we call ->config
-    # again, as we get the CAF accessor from CDICompatTestPlugin, not the one
-    # created in this package as a side-effect of this call. :-(
-    __PACKAGE__->config;
-}
-
-SKIP: {
-  skip 'Not trying to replicate the nasty CDI hackness', 2;
-  lives_ok {
-      CDICompatTestApp->setup;
-  } 'Setup app with plugins which says use base qw/Class::Accessor::Fast/';
-
-  # And the plugin's setup_finished method should have been run, as accessors
-  # are not created in MyApp until the data is written to.
-  {
-      no warnings 'once';
-      is $CDICompatTestPlugin::Data::HAS_RUN_SETUP_FINISHED, 1, 'Plugin setup_finish run';
-  }
-}
\ No newline at end of file
diff --git a/t/custom_exception_class_simple.t b/t/custom_exception_class_simple.t
new file mode 100644 (file)
index 0000000..e87ed80
--- /dev/null
@@ -0,0 +1,18 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use FindBin qw/$Bin/;
+use lib "$Bin/lib";
+use Test::More tests => 1;
+use Test::Exception;
+
+TODO: {
+    local $TODO = 'Does not work yet';
+
+lives_ok {
+    require TestAppClassExceptionSimpleTest;
+} 'Can load application';
+
+}
+
index cfb5adf..b30df89 100644 (file)
@@ -16,6 +16,8 @@ my $mvc_warnings;
 BEGIN {
     my $logger = Class::MOP::Class->create_anon_class(
     methods => {
+        debug => sub {0},
+        info  => sub {0},
         warn => sub {
             if ($_[1] =~ /switch your class names/) {
                $mvc_warnings++;
index b6d9374..a2fc0b2 100644 (file)
@@ -67,7 +67,7 @@ sub execute {
             @executed
         );
     }
-
+    no warnings 'recursion';
     return $c->SUPER::execute(@_);
 }
 
index 77e2caa..1240b0e 100644 (file)
@@ -9,7 +9,7 @@ sub execute {
     my $self = shift;
     my ( $controller, $c, $test ) = @_;
     $c->res->header( 'X-TestAppActionTestMyAction', 'MyAction works' );
-    $c->res->header( 'X-Component-Name-Action', $controller->_component_name);
+    $c->res->header( 'X-Component-Name-Action', $controller->catalyst_component_name);
     $c->res->header( 'X-Component-Instance-Name-Action', ref($controller));
     $c->res->header( 'X-Class-In-Action', $self->class);
     $self->next::method(@_);
index 5a757b0..08c7c65 100644 (file)
@@ -16,7 +16,7 @@ EOF
 
 sub body : Local {
     my ( $self, $c ) = @_;
-    
+
     my $file = "$FindBin::Bin/../lib/TestApp/Controller/Action/Streaming.pm";
     my $fh = IO::File->new( $file, 'r' );
     if ( defined $fh ) {
@@ -27,4 +27,16 @@ sub body : Local {
     }
 }
 
+sub body_large : Local {
+    my ($self, $c) = @_;
+
+    # more than one write with the default chunksize
+    my $size = 128 * 1024;
+
+    my $data = "\0" x $size;
+    open my $fh, '<', \$data;
+    $c->res->content_length($size);
+    $c->res->body($fh);
+}
+
 1;
index 9832715..68b4fd6 100644 (file)
@@ -32,7 +32,7 @@ sub COMPONENT { # Don't do this yourself, use CatalystX::Component::Traits!
 
 sub test : Local ActionClass('+TestApp::Action::TestMyAction') {
     my ($self, $c) = @_;
-    $c->res->header('X-Component-Name-Controller', $self->_component_name);
+    $c->res->header('X-Component-Name-Controller', $self->catalyst_component_name);
     $c->res->body('It works');
 }
 
diff --git a/t/lib/TestAppClassExceptionSimpleTest.pm b/t/lib/TestAppClassExceptionSimpleTest.pm
new file mode 100644 (file)
index 0000000..aef61be
--- /dev/null
@@ -0,0 +1,19 @@
+package TestAppClassExceptionSimpleTest::Exception;
+use strict;
+use warnings;
+
+sub throw {}
+
+#########
+
+package TestAppClassExceptionSimpleTest;
+use strict;
+use warnings;
+
+BEGIN { $Catalyst::Exception::CATALYST_EXCEPTION_CLASS = 'TestAppClassExceptionSimpleTest::Exception'; }
+
+use Catalyst;
+
+__PACKAGE__->setup;
+
+1;
diff --git a/t/lib/TestAppNonMooseController.pm b/t/lib/TestAppNonMooseController.pm
new file mode 100644 (file)
index 0000000..8507aba
--- /dev/null
@@ -0,0 +1,8 @@
+package TestAppNonMooseController;
+use base qw/Catalyst/;
+use Catalyst;
+
+__PACKAGE__->setup;
+
+1;
+
diff --git a/t/lib/TestAppNonMooseController/Controller/Foo.pm b/t/lib/TestAppNonMooseController/Controller/Foo.pm
new file mode 100644 (file)
index 0000000..36b036c
--- /dev/null
@@ -0,0 +1,5 @@
+package TestAppNonMooseController::Controller::Foo;
+use base qw/TestAppNonMooseController::ControllerBase/;
+
+1;
+
diff --git a/t/lib/TestAppNonMooseController/ControllerBase.pm b/t/lib/TestAppNonMooseController/ControllerBase.pm
new file mode 100644 (file)
index 0000000..406df4b
--- /dev/null
@@ -0,0 +1,5 @@
+package TestAppNonMooseController::ControllerBase;
+use base qw/Catalyst::Controller/;
+
+1;
+
index 39f475a..3d3cb3f 100644 (file)
@@ -45,10 +45,11 @@ rmtree 't/tmp/TestApp/t';
 my $port = 30000 + int rand( 1 + 10000 );
 
 my( $server, $pid );
-$pid = open3( undef, $server, undef,
-  $^X, "-I$FindBin::Bin/../lib",
+my @cmd = ($^X, "-I$FindBin::Bin/../lib", "-I$FindBin::Bin/lib",
   "$FindBin::Bin/../t/tmp/TestApp/script/testapp_server.pl", '-port',
-  $port, '-restart' )
+  $port, '-restart');
+
+$pid = open3( undef, $server, undef, @cmd )
     or die "Unable to spawn standalone HTTP server: $!";
 
 # switch to non-blocking reads so we can fail
@@ -67,11 +68,9 @@ my @files = (
     "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp.pm",
     "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp/Controller/Action/Begin.pm",
     "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp/Controller/Immutable.pm",
+    "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp/Controller/Immutable/HardToReload.pm",
 );
 
-push(@files, "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp/Controller/Immutable/HardToReload.pm")
-    if Catalyst::Engine::HTTP::Restarter::Watcher::DETECT_PACKAGE_COMPILATION();
-
 # change some files and make sure the server restarts itself
 NON_ERROR_RESTART:
 for ( 1 .. 20 ) {
@@ -84,7 +83,6 @@ for ( 1 .. 20 ) {
     # give the server time to notice the change and restart
     my $count = 0;
     my $line;
-
     while ( ( $line || '' ) !~ /can connect/ ) {
         # wait for restart message
         $line = $server->getline;
diff --git a/t/unit_controller_actions.t b/t/unit_controller_actions.t
new file mode 100644 (file)
index 0000000..26e603d
--- /dev/null
@@ -0,0 +1,26 @@
+use strict;
+use warnings;
+use Test::More tests => 4;
+
+use Catalyst ();
+{
+    package TestController;
+    use Moose;
+    BEGIN { extends 'Catalyst::Controller' }
+
+    sub action : Local {}
+
+    sub foo : Path {}
+
+    no Moose;
+}
+
+my $mock_app = Class::MOP::Class->create_anon_class( superclasses => ['Catalyst'] );
+my $app = $mock_app->name->new;
+my $controller = TestController->new($app, {actions => { foo => { Path => '/some/path' }}});
+
+ok $controller->can('_controller_actions');
+is_deeply $controller->_controller_actions => { foo => { Path => '/some/path' }};
+is_deeply $controller->{actions} => { foo => { Path => '/some/path' }}; # Back compat.
+is_deeply [ sort grep { ! /^_/ } map { $_->name } $controller->get_action_methods ], [sort qw/action foo/];
+
index 6d60a96..d054dc6 100644 (file)
@@ -100,3 +100,7 @@ is(refaddr(ClassDataTest->_hashref), refaddr($hashref3));
 is(refaddr(ClassDataTest->_scalarref), refaddr($scalarref3));
 is(refaddr(ClassDataTest->_coderef), refaddr($coderef3));
 is(ClassDataTest->_scalar, $scalar3);
+
+my $i = bless {}, 'ClassDataTest';
+$i->_scalar('foo');
+
index 42f1eac..1944ab6 100644 (file)
@@ -2,7 +2,7 @@
 # (do not forget to update the number of components in test 3 as well)
 # 5 extra tests for the loading options
 # One test for components in inner packages
-use Test::More tests => 2 + 6 * 24 + 5 + 1;
+use Test::More tests => 2 + 6 * 24 + 8 + 1;
 
 use strict;
 use warnings;
@@ -175,6 +175,9 @@ sub COMPONENT {
     my \$self = shift->next::method(\@_);
     no strict 'refs';
     *{\__PACKAGE__ . "::whoami"} = sub { return \__PACKAGE__; };
+    *${appclass}::Model::TopLevel::GENERATED::ACCEPT_CONTEXT = sub {
+        return bless {}, 'FooBarBazQuux';
+    };
     \$self;
 }
 
@@ -190,8 +193,10 @@ write_component_file([$libdir, $appclass, 'Model', 'TopLevel'], 'Nested', <<EOF)
 package ${appclass}::Model::TopLevel::Nested;
 use base 'Catalyst::Model';
 
+my \$called=0;
 no warnings 'redefine';
-sub COMPONENT { return shift->next::method(\@_); }
+sub COMPONENT { \$called++;return shift->next::method(\@_); }
+sub called { return \$called };
 1;
 
 EOF
@@ -199,6 +204,11 @@ EOF
 eval "package $appclass; use Catalyst; __PACKAGE__->setup";
 
 is($@, '', "Didn't load component twice");
+is($appclass->model('TopLevel::Nested')->called,1, 'COMPONENT called once');
+
+ok($appclass->model('TopLevel::Generated'), 'Have generated model');
+is(ref($appclass->model('TopLevel::Generated')), 'FooBarBazQuux',
+    'ACCEPT_CONTEXT in generated inner package fired as expected');
 
 $appclass = "InnerComponent";
 
index 93d08d8..03d16f6 100644 (file)
@@ -21,6 +21,9 @@ my $warnings = 0;
 use PluginTestApp;
 my $logger = Class::MOP::Class->create_anon_class(
     methods => {
+        error => sub {0},
+        debug => sub {0},
+        info => sub {0},
         warn => sub {
             if ($_[1] =~ /plugin method is deprecated/) {
                $warnings++;
@@ -40,6 +43,8 @@ is( $warnings, 0, 'no warnings' );
 #         for Catalyst 5.9
 ok( get("/run_time_plugins"),     "get ok" );
 
+local $ENV{CATALYST_DEBUG} = 0;
+
 is( $warnings, 1, '1 warning' );
 
 use_ok 'TestApp';
@@ -56,3 +61,4 @@ my @expected = qw(
 # Faux::Plugin is no longer reported
 is_deeply [ TestApp->registered_plugins ], \@expected,
   'registered_plugins() should only report the plugins for the current class';
+
index 00ee842..cbc5aac 100644 (file)
@@ -26,12 +26,17 @@ sub build_test_app_with_setup {
     return $name;
 }
 
-local %ENV; # Don't allow env variables to mess us up.
+local %ENV = %ENV;
+
+# Remove all relevant env variables to avoid accidental fail
+foreach my $name (grep { /^(CATALYST|TESTAPP)/ } keys %ENV) {
+    delete $ENV{$name};
+}
 
 {
-    my $app = build_test_app_with_setup('MyTestDebug', '-Debug');
+    my $app = build_test_app_with_setup('TestAppMyTestDebug', '-Debug');
 
-    ok my $c = MyTestDebug->new, 'Get debug app object';
+    ok my $c = $app->new, 'Get debug app object';
     ok my $log = $c->log, 'Get log object';
     isa_ok $log, 'Catalyst::Log', 'It should be a Catalyst::Log object';
     ok $log->is_warn, 'Warnings should be enabled';
@@ -43,7 +48,7 @@ local %ENV; # Don't allow env variables to mess us up.
 }
 
 {
-    my $app = build_test_app_with_setup('MyTestLogParam', '-Log=warn,error,fatal');
+    my $app = build_test_app_with_setup('TestAppMyTestLogParam', '-Log=warn,error,fatal');
 
     ok my $c = $app->new, 'Get log app object';
     ok my $log = $c->log, 'Get log object';
@@ -56,7 +61,7 @@ local %ENV; # Don't allow env variables to mess us up.
     ok !$c->debug, 'Catalyst debugging is off';
 }
 {
-    my $app = build_test_app_with_setup('MyTestNoParams');
+    my $app = build_test_app_with_setup('TestAppMyTestNoParams');
 
     ok my $c = $app->new, 'Get log app object';
     ok my $log = $c->log, 'Get log object';
@@ -72,12 +77,12 @@ my $log_meta = Class::MOP::Class->create_anon_class(
     methods => { map { $_ => sub { 0 } } qw/debug error fatal info warn/ },
 );
 {
-    package MyTestAppWithOwnLogger;
+    package TestAppWithOwnLogger;
     use base qw/Catalyst/;
     __PACKAGE__->log($log_meta->new_object);
     __PACKAGE__->setup('-Debug');
 }
 
-ok my $c = MyTestAppWithOwnLogger->new, 'Get with own logger app object';
+ok my $c = TestAppWithOwnLogger->new, 'Get with own logger app object';
 ok $c->debug, '$c->debug is true';
 
index 401ea99..1406944 100644 (file)
@@ -27,10 +27,15 @@ sub test_log_object {
     }
 }
 
-local %ENV; # Ensure blank or someone, somewhere will fail..
+local %ENV = %ENV;
+
+# Remove all relevant env variables to avoid accidental fail
+foreach my $name (grep { /^(CATALYST|TESTAPP)/ } keys %ENV) {
+    delete $ENV{$name};
+}
 
 {
-    my $app = mock_app('TestLogAppParseLevels');
+    my $app = mock_app('TestAppParseLogLevels');
     $app->setup_log('error,warn');
     ok !$app->debug, 'Not in debug mode';
     test_log_object($app->log,
@@ -42,8 +47,9 @@ local %ENV; # Ensure blank or someone, somewhere will fail..
     );
 }
 {
-    local %ENV = ( CATALYST_DEBUG => 1 );
-    my $app = mock_app('TestLogAppDebugEnvSet');
+    local %ENV = %ENV;
+    $ENV{CATALYST_DEBUG} = 1;
+    my $app = mock_app('TestAppLogDebugEnvSet');
     $app->setup_log('');
     ok $app->debug, 'In debug mode';
     test_log_object($app->log,
@@ -55,8 +61,9 @@ local %ENV; # Ensure blank or someone, somewhere will fail..
     );
 }
 {
-    local %ENV = ( CATALYST_DEBUG => 0 );
-    my $app = mock_app('TestLogAppDebugEnvUnset');
+    local %ENV = %ENV;
+    $ENV{CATALYST_DEBUG} = 0;
+    my $app = mock_app('TestAppLogDebugEnvUnset');
     $app->setup_log('warn');
     ok !$app->debug, 'Not In debug mode';
     test_log_object($app->log,
@@ -68,7 +75,7 @@ local %ENV; # Ensure blank or someone, somewhere will fail..
     );
 }
 {
-    my $app = mock_app('TestLogAppEmptyString');
+    my $app = mock_app('TestAppLogEmptyString');
     $app->setup_log('');
     ok !$app->debug, 'Not In debug mode';
     # Note that by default, you get _all_ the log levels turned on
@@ -81,7 +88,7 @@ local %ENV; # Ensure blank or someone, somewhere will fail..
     );
 }
 {
-    my $app = mock_app('TestLogAppDebugOnly');
+    my $app = mock_app('TestAppLogDebugOnly');
     $app->setup_log('debug');
     ok $app->debug, 'In debug mode';
     test_log_object($app->log,
index 8cc979f..11ef840 100644 (file)
@@ -22,40 +22,46 @@ my $mock_log = Class::MOP::Class->create_anon_class(
 sub mock_app {
     my $name = shift;
     %log_messages = (); # Flatten log messages.
-    print "Setting up mock application: $name\n";
     my $meta = Moose->init_meta( for_class => $name );
     $meta->superclasses('Catalyst');
     $meta->add_method('log', sub { $mock_log }); 
     return $meta->name;
 }
 
-local %ENV; # Ensure blank or someone, somewhere will fail..
+local %ENV = %ENV;
+
+# Remove all relevant env variables to avoid accidental fail
+foreach my $name (grep { /^(CATALYST|TESTAPP)/ } keys %ENV) {
+    delete $ENV{$name};
+}
 
 {
-    my $app = mock_app('TestNoStats');
+    my $app = mock_app('TestAppNoStats');
     $app->setup_stats();
     ok !$app->use_stats, 'stats off by default';
 }
 {
-    my $app = mock_app('TestStats');
+    my $app = mock_app('TestAppStats');
     $app->setup_stats(1);
     ok $app->use_stats, 'stats on if you say >setup_stats(1)';
 }
 {
-    my $app = mock_app('TestStatsDebugTurnsStatsOn');
+    my $app = mock_app('TestAppStatsDebugTurnsStatsOn');
     $app->meta->add_method('debug' => sub { 1 });
     $app->setup_stats();
     ok $app->use_stats, 'debug on turns stats on';
 }
 {
-    local %ENV = ( CATALYST_STATS => 1 );
-    my $app = mock_app('TestStatsAppStatsEnvSet');
+    local %ENV = %ENV;
+    $ENV{CATALYST_STATS} = 1;
+    my $app = mock_app('TestAppStatsEnvSet');
     $app->setup_stats();
     ok $app->use_stats, 'ENV turns stats on';
 }
 {
-    local %ENV = ( CATALYST_STATS => 0 );
-    my $app = mock_app('TestStatsAppStatsEnvUnset');
+    local %ENV = %ENV;
+    $ENV{CATALYST_STATS} = 0;
+    my $app = mock_app('TestAppStatsEnvUnset');
     $app->meta->add_method('debug' => sub { 1 });
     $app->setup_stats(1);
     ok !$app->use_stats, 'ENV turns stats off, even when debug on and ->setup_stats(1)';
index cb3c1e2..3b91ef2 100644 (file)
@@ -1,23 +1,12 @@
-use Catalyst ();
+use strict;
+use warnings;
 
-{
-    package TestApp;
-    use base qw/Catalyst/;
-}
-{
-    package TestApp::Controller::Base;
-    use base qw/Catalyst::Controller/;
-}
-{
-    package TestApp::Controller::Other;
-    use base qw/TestApp::Controller::Base/;
-}
-
-TestApp->setup_component('TestApp::Controller::Other');
-TestApp->setup_component('TestApp::Controller::Base');
+use FindBin;
+use lib "$FindBin::Bin/lib";
 
 use Test::More tests => 1;
 use Test::Exception;
+use TestAppNonMooseController;
 
 # Metaclass init order causes fail.
 # There are TODO tests in Moose for this, see
@@ -25,6 +14,6 @@ use Test::Exception;
 # after which the evil kludge in core can die in a fire.
 
 lives_ok {
-    TestApp::Controller::Base->get_action_methods
+    TestAppNonMooseController::ControllerBase->get_action_methods
 } 'Base class->get_action_methods ok when sub class initialized first';
 
index 928b48e..676f354 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 12;
+use Test::More tests => 13;
 use Time::HiRes qw/gettimeofday/;
 use Tree::Simple;
 
@@ -19,6 +19,8 @@ BEGIN { use_ok("Catalyst::Stats") };
     my $stats = Catalyst::Stats->new;
     is (ref($stats), "Catalyst::Stats", "new");
 
+    is_deeply([ $stats->created ], [0, 0], "created time");
+
     my @expected; # level, string, time
 
     $fudge_t[0] = 1;