Merge 'trunk' into 'param_filtering'
Tomas Doran [Tue, 1 Dec 2009 01:08:22 +0000 (01:08 +0000)]
r10824@t0mlaptop (orig r10823):  autarch | 2009-07-07 21:58:31 +0100
Deleted the old Restarter and associated code.

Also removed the dep on File::Modified
r10831@t0mlaptop (orig r10830):  t0m | 2009-07-08 21:11:57 +0100
U R DOIN IT WRONG.
r10836@t0mlaptop (orig r10835):  t0m | 2009-07-08 23:12:29 +0100
More ->config fixes + Changelog
r10852@t0mlaptop (orig r10851):  t0m | 2009-07-11 13:51:07 +0100
Less lies in the deprecated block comment in Dispatcher.pm as it's throwing people off
r10862@t0mlaptop (orig r10861):  groditi | 2009-07-11 23:07:47 +0100
private_path method for actions that returns a string suitable for use in forward and unit tests for the rest of catalyst::Action
r10865@t0mlaptop (orig r10864):  t0m | 2009-07-12 01:56:51 +0100
Fix test
r10866@t0mlaptop (orig r10865):  t0m | 2009-07-12 01:57:19 +0100
Refactor to remove warning
r10885@t0mlaptop (orig r10884):  t0m | 2009-07-14 21:25:03 +0100
Fix Makefile.PL to actually do the right thing on Lepoard (alledgedly), and encourage someone to contribute to maintaining our protection against Apple :)
r10892@t0mlaptop (orig r10891):  dandv | 2009-07-16 02:12:59 +0100
Fixed POD links to get and request
r10893@t0mlaptop (orig r10892):  dandv | 2009-07-16 06:24:10 +0100
Could not have made a more insignificant patch
r10898@t0mlaptop (orig r10897):  t0m | 2009-07-16 22:05:25 +0100
Special move for CX::Component::Traits. No tests, please don't look.
r10899@t0mlaptop (orig r10898):  t0m | 2009-07-16 22:12:49 +0100
Remove 10897, this hack kinda works, but then leads to more issues. Gonna branch
r10900@t0mlaptop (orig r10899):  t0m | 2009-07-16 22:24:11 +0100
Write that down
r10915@t0mlaptop (orig r10914):  dandv | 2009-07-17 06:18:22 +0100
Hyperlinked POD entry for Catalysy::Request->args
r10941@t0mlaptop (orig r10940):  jester | 2009-07-22 13:46:29 +0100
Changed link from C::Base to C::Controller; fixed my alias
r10962@t0mlaptop (orig r10961):  hobbs | 2009-07-23 05:46:43 +0100
Depend on Module::Pluggable 3.9 to resolve a bug with inner packages in tests.

r10963@t0mlaptop (orig r10962):  hobbs | 2009-07-23 10:32:08 +0100
Test and Changelog entry for r10961.

r10981@t0mlaptop (orig r10980):  t0m | 2009-07-25 22:05:19 +0100
Remove dead and unused method
r10985@t0mlaptop (orig r10984):  autarch | 2009-07-26 03:14:23 +0100
fix spelling of attributes in the test name
r10986@t0mlaptop (orig r10985):  dandv | 2009-07-26 08:13:19 +0100
Fixed a bunch of POD hyperlinks in Catalyst.pm and minor punctuation in Catalyst::Action
r10994@t0mlaptop (orig r10993):  kmx | 2009-07-28 16:26:44 +0100
C::Engine::FastCGI (_fix_env) - Microsoft IIS on Windows 2008 R2 has version string "IIS/7.5" that was not supported; this patch makes test condition more general, accepting versions from IIS/6.0 to IIS/9.9 (should be enough for a while)
r10995@t0mlaptop (orig r10994):  hobbs | 2009-07-29 01:33:25 +0100
Rewrite the POD for $c->uri_for().

Reintroduce some bits of information that were lost in 5.7->5.8, and remove
a misleading statement about $c->action. Recommend the use of uri_for_action
with a private action path.

r10996@t0mlaptop (orig r10995):  hobbs | 2009-07-29 01:59:19 +0100
Update Changes and add me to Contributors
r10997@t0mlaptop (orig r10996):  hobbs | 2009-07-29 02:06:09 +0100
Add konobi to contributors
r10998@t0mlaptop (orig r10997):  hobbs | 2009-07-29 02:35:11 +0100
Changes entry for r10993
r11009@t0mlaptop (orig r11008):  t0m | 2009-07-30 15:31:26 +0100
Add to TODO so I don't have to grep backlog later when I have tuits
r11013@t0mlaptop (orig r11012):  t0m | 2009-07-31 02:46:00 +0100
Large TODO update
r11019@t0mlaptop (orig r11018):  t0m | 2009-08-01 01:39:39 +0100
Merge branch pass_component_names:

svn merge -r  10899:10927  http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/branches/pass_component_names
r11021@t0mlaptop (orig r11020):  t0m | 2009-08-01 03:00:23 +0100
Aww, crap, fail. merge 10927:HEAD from pass_component_names
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.
r11369@t0mlaptop (orig r11339):  marcus | 2009-09-09 18:05:32 +0100
un-TODO passing TODO tests
r11370@t0mlaptop (orig r11340):  marcus | 2009-09-09 18:08:03 +0100
Prepare for release
r11374@t0mlaptop (orig r11344):  groditi | 2009-09-09 22:06:59 +0100
add myself to contributors
r11375@t0mlaptop (orig r11345):  t0m | 2009-09-10 01:13:56 +0100
Fix warnings in upcoming moose
r11377@t0mlaptop (orig r11347):  t0m | 2009-09-10 02:14:13 +0100
 r11046@t0mlaptop (orig r11045):  yousef | 2009-08-07 00:07:07 +0100
 Moved action methods from t/lib/TestApp.pm to t/lib/Test/Controller/Root.pm. Uncommented the if statement in lib/Catalyst/Controller.pm that checks for actions in the appclass.

r11378@t0mlaptop (orig r11348):  t0m | 2009-09-10 02:20:55 +0100
Eat the merge mark, svk hates me.
r11379@t0mlaptop (orig r11349):  t0m | 2009-09-10 03:13:04 +0100
Blargh. Merge branch deprecate_appclass_actions manually, with svn merge http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/trunk http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/branches/deprecate_appclass_actions . after I forgot -l on svk push, but ctrl-C after the first rev meant svk had already committed a merge mark and re-merging did nothing, and removing it didn't do the right thing. Fail cake..
r11380@t0mlaptop (orig r11350):  hobbs | 2009-09-10 08:20:31 +0100
Rework the C<< $c->go >> documentation a little, hopefully it's more clear.

r11382@t0mlaptop (orig r11352):  autarch | 2009-09-11 03:48:29 +0100
Preserve immutable_options when temporarily making a class mutable

r11383@t0mlaptop (orig r11353):  t0m | 2009-09-11 09:18:09 +0100
Work with old and new Moose
r11393@t0mlaptop (orig r11363):  autarch | 2009-09-14 19:37:25 +0100
The warning about a class having mutable ancestors has been removed (and was never in a non-dev Moose release)

r11396@t0mlaptop (orig r11366):  t0m | 2009-09-15 21:48:19 +0100
Remove what is now lies from Changes. Bump all the deps which need to be bumped to not crap warnings everywhere
r11399@t0mlaptop (orig r11369):  t0m | 2009-09-16 18:14:29 +0100
Changelog
r11400@t0mlaptop (orig r11370):  t0m | 2009-09-16 18:15:52 +0100
Now we depend on latest Moose we are certain to have immutable options
r11401@t0mlaptop (orig r11371):  t0m | 2009-09-17 09:52:34 +0100
-short is dead, RT#49771
r11402@t0mlaptop (orig r11372):  t0m | 2009-09-17 09:52:52 +0100
Add note about actions in appclass being deprecated
r11403@t0mlaptop (orig r11373):  t0m | 2009-09-17 09:54:45 +0100
Add note about ::[MVC]:: warnings
r11404@t0mlaptop (orig r11374):  t0m | 2009-09-17 09:58:15 +0100
Re-space current release changelog to align with the rest. Move -short changelog to the right place.
r11405@t0mlaptop (orig r11375):  rafl | 2009-09-17 10:33:28 +0100
Version 5.80013.
r11407@t0mlaptop (orig r11377):  t0m | 2009-09-17 14:32:16 +0100
Well, that got forgotten, oops
r11426@t0mlaptop (orig r11396):  rafl | 2009-09-20 15:01:45 +0100
Fix a syntax error in the ContextClosure pod.
r11427@t0mlaptop (orig r11397):  rafl | 2009-09-20 15:01:51 +0100
Use clean instead of autoclean in the ContextClosure synopsis until we've fixed the issues with that and MXMA.
r11428@t0mlaptop (orig r11398):  gbjk | 2009-09-21 15:05:17 +0100
- Fix go / visit expecting captures and arguments in reverse order.

r11429@t0mlaptop (orig r11399):  mateu | 2009-09-21 19:57:14 +0100
Update $c->forward and $c->state documentation to address scalar context.
r11430@t0mlaptop (orig r11400):  t0m | 2009-09-23 15:48:06 +0100
Dep bump
r11452@t0mlaptop (orig r11422):  t0m | 2009-09-25 13:03:50 +0100
Remove warnings for using Catalyst::Dispatcher->dispatch_types
r11459@t0mlaptop (orig r11429):  t0m | 2009-09-27 13:27:41 +0100
Optional test not optional for authors
r11460@t0mlaptop (orig r11430):  t0m | 2009-09-27 13:33:05 +0100
Make r11422 not break stuff - idiot :(
r11487@t0mlaptop (orig r11457):  t0m | 2009-10-05 22:59:47 +0100
 r11483@t0mlaptop (orig r11453):  abraxxa | 2009-10-05 12:57:34 +0100
 Improved the suggested fix warning when component resolution uses regex fallback for fully qualified component names.
 Added disable_component_resolution_regex_fallback config option to switch off regex fallback for component resolution.

r11488@t0mlaptop (orig r11458):  t0m | 2009-10-05 22:59:52 +0100
 r11486@t0mlaptop (orig r11456):  t0m | 2009-10-05 22:59:01 +0100
 Tidy up changelog/attribution

r11503@t0mlaptop (orig r11468):  ilmari | 2009-10-06 16:30:41 +0100
Set ->request on the response object i Catalyst::Test::local_request--This line, and those below, will be ignored--

M    t/unit_load_catalyst_test.t
M    lib/Catalyst/Test.pm
M    Changes

r11519@t0mlaptop (orig r11484):  phaylon | 2009-10-07 18:21:47 +0100
added stub config section (incl TODO) to Cat.pm for things like 'current_view'
r11548@t0mlaptop (orig r11513):  caelum | 2009-10-12 17:18:22 +0100
fix uninitialized warning in ACL
r11549@t0mlaptop (orig r11514):  caelum | 2009-10-12 17:22:08 +0100
better fix for uninitialized warning
r11550@t0mlaptop (orig r11515):  t0m | 2009-10-12 18:10:32 +0100
Less cargo cult madness
r11554@t0mlaptop (orig r11519):  caelum | 2009-10-13 15:37:02 +0100
more correct fix for uninitialized warning from ACL
r11556@t0mlaptop (orig r11521):  dhoss | 2009-10-14 01:14:42 +0100
Snow Leopard uses COPYFILE_DISABLE
r11557@t0mlaptop (orig r11522):  dhoss | 2009-10-14 01:20:06 +0100
fixed regex for next mac codename/version, will have to actually figure out what the 10.7 codename is when it arrives
r11558@t0mlaptop (orig r11523):  dhoss | 2009-10-14 01:23:45 +0100
Attempted to make the error message more obvious
r11561@t0mlaptop (orig r11526):  dhoss | 2009-10-14 01:50:26 +0100
fixed error message for mac osx 10.7
r11568@t0mlaptop (orig r11533):  hobbs | 2009-10-15 03:32:28 +0100
Give people a pointer to chase if they're looking for info on $c->req->user

r11574@t0mlaptop (orig r11539):  t0m | 2009-10-15 22:19:26 +0100
Add docs I promised for  r11484
r11622@t0mlaptop (orig r11587):  jshirley | 2009-10-16 21:06:19 +0100
The longawaited nginx patch to support non-root apps, and some pod
r11623@t0mlaptop (orig r11588):  jshirley | 2009-10-16 21:07:29 +0100
Changes for nginx patches
r11624@t0mlaptop (orig r11589):  jshirley | 2009-10-16 21:08:55 +0100
My favorite color is clear and I like to eat rocks
r11670@t0mlaptop (orig r11635):  t0m | 2009-10-19 18:02:59 +0100
Remove warnings from duplicate action declerations
r11675@t0mlaptop (orig r11640):  poisonbit | 2009-10-20 21:12:46 +0100
Example added to #Actions_in_your_application_class

r11676@t0mlaptop (orig r11641):  poisonbit | 2009-10-20 21:32:41 +0100
Formating (a lost space and line break)

r11677@t0mlaptop (orig r11642):  poisonbit | 2009-10-20 21:34:45 +0100
More regresion from 11640, correcting parentheses and endpoint.

r11678@t0mlaptop (orig r11643):  poisonbit | 2009-10-20 22:08:47 +0100
Change in actions inside roles.
http://bobtfish.livejournal.com/264317.html

r11679@t0mlaptop (orig r11644):  poisonbit | 2009-10-20 23:16:03 +0100
Fixes to pass podchecker OK

r11714@t0mlaptop (orig r11679):  rafl | 2009-10-28 23:54:56 +0000
Enable Catalyst::Utils::home() to find home within Dist::Zilla built dists.

Courtesy of nperez.
r11716@t0mlaptop (orig r11681):  t0m | 2009-10-29 00:43:07 +0000
Make URI a link to make it super obvious
r11796@t0mlaptop (orig r11761):  t0m | 2009-11-05 00:11:15 +0000
Need newer LWP for tests to pass as suggested on list by Jose Luis Martinez
r11811@t0mlaptop (orig r11776):  altreus | 2009-11-06 17:09:51 +0000
Add doc for no-args call to ->uri_for
r11813@t0mlaptop (orig r11778):  dhoss | 2009-11-06 17:13:27 +0000
fixed options passed to devel server so that author tests pass
r11814@t0mlaptop (orig r11779):  altreus | 2009-11-06 17:14:49 +0000
Amend doc to not mention using undef in ->uri_for
r11816@t0mlaptop (orig r11781):  t0m | 2009-11-07 16:50:59 +0000
Back out change from -port to -l - svn merge -r 11778:11777
r11823@t0mlaptop (orig r11788):  rafl | 2009-11-09 22:21:19 +0000
Make request->body fail when used as a writer.
r11824@t0mlaptop (orig r11789):  t0m | 2009-11-10 19:51:33 +0000
Fix changelog, me--
r11825@t0mlaptop (orig r11790):  t0m | 2009-11-10 19:56:09 +0000
Warn on case_sensitive being set, remove documentation
r11827@t0mlaptop (orig r11792):  t0m | 2009-11-10 21:36:06 +0000
Return 1, only currently works by chance
r11828@t0mlaptop (orig r11793):  t0m | 2009-11-10 21:37:26 +0000
Also retarded
r11829@t0mlaptop (orig r11794):  t0m | 2009-11-10 21:41:27 +0000
And lets not change behaviour with the log flush change..
r11836@t0mlaptop (orig r11801):  t0m | 2009-11-12 01:12:05 +0000
Bring the changelog up to date.
r11839@t0mlaptop (orig r11804):  t0m | 2009-11-12 01:44:46 +0000
 r11462@t0mlaptop (orig r11432):  rafl | 2009-09-27 16:06:26 +0100
 More aggregated tests.
 r11463@t0mlaptop (orig r11433):  rafl | 2009-09-27 16:06:36 +0100
 Fix a couple of aggregation warnings.
 r11464@t0mlaptop (orig r11434):  rafl | 2009-09-27 16:06:51 +0100
 More aggregation.
 r11465@t0mlaptop (orig r11435):  rafl | 2009-09-27 16:28:04 +0100
 Make things run again with aggregation disabled.
 r11838@t0mlaptop (orig r11803):  t0m | 2009-11-12 01:39:56 +0000
 Patch up changes to tests into new location. This merges parts of the following commits which were missed by svk:

 -r11456:11457 http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/trunk
 -r11467:11468 http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Runtime/5.80/trunk

r11841@t0mlaptop (orig r11806):  bricas | 2009-11-12 17:58:02 +0000
remove duplicate changelog entry
r11847@t0mlaptop (orig r11812):  t0m | 2009-11-12 23:57:15 +0000
 r11668@t0mlaptop (orig r11633):  t0m | 2009-10-19 17:53:27 +0100
 Branch for uri encoding things in uri_for in some way that means you can round trip path parts like '24/7', but without totally breaking backward compatibility this time hopefully.

 r11669@t0mlaptop (orig r11634):  t0m | 2009-10-19 17:54:08 +0100
 Well, this fixes my current issue, and doesn't seem to break any tests.. This likely means that the tests are still shit
 r11769@t0mlaptop (orig r11734):  t0m | 2009-11-04 19:17:33 +0000
 Needed for authors to run optional http test
 r11833@t0mlaptop (orig r11798):  t0m | 2009-11-12 00:22:06 +0000
 Tests, fix args as well as captureargs and be less violent - only encode /
 r11840@t0mlaptop (orig r11805):  rafl | 2009-11-12 16:08:57 +0000
 trailing whitespace
 r11843@t0mlaptop (orig r11808):  t0m | 2009-11-12 23:41:17 +0000
 Tidy up a bit
 r11845@t0mlaptop (orig r11810):  t0m | 2009-11-12 23:46:28 +0000
 Changelog
 r11846@t0mlaptop (orig r11811):  t0m | 2009-11-12 23:56:36 +0000
 Don't fail the live tests by only looking for http://localhost/etc..

r11858@t0mlaptop (orig r11823):  t0m | 2009-11-14 17:26:04 +0000
Pod patch
r11860@t0mlaptop (orig r11825):  t0m | 2009-11-14 17:30:26 +0000
Pod fixes re RT#51489
r11914@t0mlaptop (orig r11879):  rafl | 2009-11-17 23:00:32 +0000
Merge branch 'exception_interface'

* exception_interface:
  Use MooseX::Role::WithOverloading.
  Add Exception::Interface and Exception::Basic. Make ::Base, ::Go and ::Detach use them.
  Create branch exception_interface
r11953@t0mlaptop (orig r11918):  t0m | 2009-11-19 21:58:59 +0000
Add Pod for all the new exception classes
r11954@t0mlaptop (orig r11919):  t0m | 2009-11-19 22:00:27 +0000
Rename http server test as it is not optional for authors
r11978@t0mlaptop (orig r11943):  rafl | 2009-11-20 06:22:44 +0000
Fix a doc typo.

Also trim some trailing whitespace.
r11979@t0mlaptop (orig r11944):  rafl | 2009-11-20 06:22:51 +0000
Remove some docs for Exception::Go and ::Detach.

Users really shouldn't care.
r11980@t0mlaptop (orig r11945):  rafl | 2009-11-20 07:05:08 +0000
Depend on MX::Role::WithOverloading 0.03 to make sure things work out on 5.8.8 and older.
r11986@t0mlaptop (orig r11951):  rafl | 2009-11-21 01:30:07 +0000
Remove duplicate changelog entry.
r11987@t0mlaptop (orig r11952):  rafl | 2009-11-21 01:43:12 +0000
Improve Exception::Interface docs.
r11988@t0mlaptop (orig r11953):  rafl | 2009-11-21 01:43:28 +0000
More changelogging.
r11989@t0mlaptop (orig r11954):  rafl | 2009-11-21 01:43:57 +0000
Refer to the right ticket in Changes.
r11990@t0mlaptop (orig r11955):  rafl | 2009-11-21 02:31:02 +0000
Version 5.80014.
r11996@t0mlaptop (orig r11961):  zby | 2009-11-21 13:03:43 +0000
warning for plugins inheriting from Catayst::Component
r11998@t0mlaptop (orig r11963):  t0m | 2009-11-22 12:57:30 +0000
Chop out that crap, not needed
r11999@t0mlaptop (orig r11964):  t0m | 2009-11-22 13:01:09 +0000
Do not be @ISA Controller, that's hideous dumb and now warns
r12000@t0mlaptop (orig r11965):  t0m | 2009-11-22 13:01:48 +0000
Do not use NEXT, like it says in the comments
r12001@t0mlaptop (orig r11966):  t0m | 2009-11-22 13:04:50 +0000
Fix unicode issues in CGI and FastCGI engines
r12002@t0mlaptop (orig r11967):  t0m | 2009-11-22 13:08:47 +0000
Changelog, adjust warning text, bump versions for a dev release. The 'we do get Class::C3::Adopt::NEXT warnings test is now broken, no idea why, will look later.
r12003@t0mlaptop (orig r11968):  t0m | 2009-11-22 19:42:30 +0000
Different phrasing for different versions
r12004@t0mlaptop (orig r11969):  t0m | 2009-11-22 19:53:00 +0000
Whoops, fix typo
r12005@t0mlaptop (orig r11970):  t0m | 2009-11-22 19:58:31 +0000
It actually wants 'true', make that more explicit
r12006@t0mlaptop (orig r11971):  t0m | 2009-11-22 19:59:04 +0000
release 5.80014_01
r12008@t0mlaptop (orig r11973):  t0m | 2009-11-22 20:08:28 +0000
Notabs is author only
r12009@t0mlaptop (orig r11974):  t0m | 2009-11-22 20:11:17 +0000
Pod tests are also author only
r12010@t0mlaptop (orig r11975):  t0m | 2009-11-22 20:13:06 +0000
Changelog
r12013@t0mlaptop (orig r11978):  t0m | 2009-11-23 21:25:19 +0000
Don't do bytes::length, just use length, tests to demonstrate the issue
r12014@t0mlaptop (orig r11979):  t0m | 2009-11-23 21:45:55 +0000
Nasty hack for fastcgi, fixes gitalist
r12021@t0mlaptop (orig r11986):  t0m | 2009-11-23 22:57:40 +0000
Have a new conflict statement
r12035@t0mlaptop (orig r12000):  t0m | 2009-11-24 09:50:07 +0000
Trivial Pod fixes
r12055@t0mlaptop (orig r12020):  t0m | 2009-11-26 01:07:08 +0000
Remove test spraff
r12057@t0mlaptop (orig r12022):  t0m | 2009-11-26 01:21:22 +0000
Back out 11979 until I work out why IPC::Run is getting hold of the FCGI file handle
r12070@t0mlaptop (orig r12035):  t0m | 2009-11-26 21:29:32 +0000
Fix test on bleadperl RT#52100
r12095@t0mlaptop (orig r12060):  gshank | 2009-11-27 22:43:11 +0000
testcase for Chained bug - dispatches to wrong action

r12108@t0mlaptop (orig r12073):  rafl | 2009-11-29 16:43:17 +0000
Depend on a recent leakchecker to stop everything from crapping over itself if PadWalker is too old.
r12110@t0mlaptop (orig r12075):  t0m | 2009-11-29 17:16:40 +0000
 r11583@nc10 (orig r10642):  dhoss | 2009-06-24 22:18:13 +0100
 created better scripts branch

 r11584@nc10 (orig r10643):  dhoss | 2009-06-24 22:21:03 +0100
 initial script commit

 r11585@nc10 (orig r10644):  dhoss | 2009-06-24 23:56:42 +0100
 initial ScriptRunner checkin

 r11588@nc10 (orig r10647):  dhoss | 2009-06-25 01:54:12 +0100
 added a test application to get the new scripts working
 created Catalyst::ScriptRunner, Catalyst::Script::*
 got Catalyst::Script::FastCGI running
 wrote a test for Catalyst::Script::FastCGI, but it fails for some reason

 r11590@nc10 (orig r10649):  dhoss | 2009-06-25 02:10:57 +0100
 added dev_server test, poked Catalyst::Script::Create

 r11591@nc10 (orig r10650):  dhoss | 2009-06-25 02:21:18 +0100
 fixed test server, blech

 r11592@nc10 (orig r10651):  dhoss | 2009-06-25 02:28:41 +0100
 pulled crap out of testapp_server

 r11593@nc10 (orig r10652):  dhoss | 2009-06-25 02:41:39 +0100
 fixed server start

 r11594@nc10 (orig r10653):  dhoss | 2009-06-25 03:03:00 +0100
 fixed Server and testapp_server.pl. Test still wonky

 r11595@nc10 (orig r10654):  dhoss | 2009-06-25 03:15:18 +0100
 poked at t/start_dev_server.t
 corrected Server to start with HTTP not CGI

 r11597@nc10 (orig r10656):  dhoss | 2009-06-25 03:30:41 +0100
 updated testapp_cgi.pl
 updated CGI

 r11598@nc10 (orig r10657):  dhoss | 2009-06-25 04:11:14 +0100
 added more to Test, added testapp_test, and worked on start_fcgi

 r11604@nc10 (orig r10663):  dhoss | 2009-06-25 11:37:12 +0100
 updated Makefil.PL

 r11624@nc10 (orig r10683):  dhoss | 2009-06-26 20:46:17 +0100
 updated so that if their class doesn't load, we use ours.

 r11650@nc10 (orig r10709):  dhoss | 2009-06-28 21:33:41 +0100
 added name to contributors list

 r11660@nc10 (orig r10719):  t0m | 2009-06-29 00:12:11 +0100
 Kind of, sort of make the server work, except it doesn't
 r11685@nc10 (orig r10744):  dhoss | 2009-06-30 19:28:47 +0100
 fixed Server

 r11726@nc10 (orig r10785):  dhoss | 2009-07-04 01:41:40 +0100
 help option now has a short option

 r11727@nc10 (orig r10786):  dhoss | 2009-07-04 01:44:15 +0100
 fork now has a short option

 r11728@nc10 (orig r10787):  dhoss | 2009-07-04 01:45:19 +0100
 listen now has a short option

 r11729@nc10 (orig r10788):  dhoss | 2009-07-04 01:49:39 +0100
 doez haz pidfile short opt

 r11730@nc10 (orig r10789):  dhoss | 2009-07-04 01:51:12 +0100
 doez haz keepalive short opt

 r11731@nc10 (orig r10790):  dhoss | 2009-07-04 01:51:35 +0100
 changed pf => pid

 r11732@nc10 (orig r10791):  dhoss | 2009-07-04 01:53:16 +0100
 background now has a short opshun

 r11733@nc10 (orig r10792):  dhoss | 2009-07-04 01:54:29 +0100
 restart has short option

 r11734@nc10 (orig r10793):  dhoss | 2009-07-04 01:56:16 +0100
 restart_delay HAZ OPSHUN

 r11735@nc10 (orig r10794):  dhoss | 2009-07-04 01:57:11 +0100
 restart regex has a short option

 r11736@nc10 (orig r10795):  dhoss | 2009-07-04 01:58:02 +0100
 follow_symlinks has short option

 r11737@nc10 (orig r10796):  dhoss | 2009-07-04 03:01:44 +0100
 Updated testapp_server
 broke Script::Server, why?!

 r11738@nc10 (orig r10797):  dhoss | 2009-07-04 03:57:13 +0100
 added namespace::autoclean to all the helper classes
 removed a redundant use Catalyst::Engine::HTTP

 r11739@nc10 (orig r10798):  dhoss | 2009-07-04 04:25:25 +0100
 added warn to setup. sigh. doesn't appear it's getting called, unless
 i'm way off.

 r11740@nc10 (orig r10799):  dhoss | 2009-07-04 04:27:41 +0100
 untarded!

 r11741@nc10 (orig r10800):  dhoss | 2009-07-04 04:28:15 +0100
 really untarded

 r11778@nc10 (orig r10837):  dhoss | 2009-07-11 00:27:12 +0100
 removed except meta stuff since we're using autoclean

 r11779@nc10 (orig r10838):  dhoss | 2009-07-11 01:06:53 +0100
 fixed Catalyst::Script::Server so app doesn't have to be a cmd line opt

 r11780@nc10 (orig r10839):  dhoss | 2009-07-11 01:14:43 +0100
 removed all required => 0

 r11781@nc10 (orig r10840):  dhoss | 2009-07-11 01:18:23 +0100
 removed "broken" commetn

 r11782@nc10 (orig r10841):  dhoss | 2009-07-11 01:19:41 +0100
 removed debug warn

 r11783@nc10 (orig r10842):  dhoss | 2009-07-11 01:31:58 +0100
 removed default => 0s

 r11784@nc10 (orig r10843):  dhoss | 2009-07-11 01:34:54 +0100
 added debug option

 r11785@nc10 (orig r10844):  dhoss | 2009-07-11 02:50:11 +0100
 fasterized

 r11786@nc10 (orig r10845):  dhoss | 2009-07-11 03:21:41 +0100
 added restarter code

 r11787@nc10 (orig r10846):  dhoss | 2009-07-11 03:24:02 +0100
 fixed follow_symlinks option in restarter code

 r11788@nc10 (orig r10847):  dhoss | 2009-07-11 03:33:44 +0100
 cleaned up sub runner

 r11793@nc10 (orig r10852):  t0m | 2009-07-11 19:10:02 +0100
 Strip trailing spaces
 r11801@nc10 (orig r10860):  autarch | 2009-07-11 20:32:11 +0100
 Get the restarter running
 r11809@nc10 (orig r10868):  t0m | 2009-07-12 18:15:09 +0100
 Too slow
 r11810@nc10 (orig r10869):  t0m | 2009-07-12 18:27:36 +0100
 And unfuck so the app name is passed properly
 r11831@nc10 (orig r10890):  dhoss | 2009-07-15 22:41:11 +0100
 -d and --debug work for me

 r11834@nc10 (orig r10893):  dhoss | 2009-07-16 10:25:47 +0100
 added Deploy prototype

 r11843@nc10 (orig r10902):  dhoss | 2009-07-17 01:52:56 +0100
 untarded and added documentation

 r11844@nc10 (orig r10903):  dhoss | 2009-07-17 01:53:38 +0100
 don't need  -except => [ qw(meta) ] with autoclean

 r11845@nc10 (orig r10904):  dhoss | 2009-07-17 02:00:54 +0100
 added documentation, surely needs refining

 r11846@nc10 (orig r10905):  dhoss | 2009-07-17 02:01:25 +0100
 removed -except => qw[meta]

 r11847@nc10 (orig r10906):  dhoss | 2009-07-17 02:04:12 +0100
 cleaned up

 r11848@nc10 (orig r10907):  dhoss | 2009-07-17 02:12:07 +0100
 added documentation

 r11849@nc10 (orig r10908):  dhoss | 2009-07-17 02:13:28 +0100
 fasterized

 r11850@nc10 (orig r10909):  dhoss | 2009-07-17 02:15:04 +0100
 added MX::Types::Moose

 r11851@nc10 (orig r10910):  dhoss | 2009-07-17 02:24:44 +0100
 added MX::Types::Moose, cleaned up moar

 r11852@nc10 (orig r10911):  dhoss | 2009-07-17 02:43:29 +0100
 created proof of working app

 r11853@nc10 (orig r10912):  dhoss | 2009-07-17 02:44:07 +0100
 removed proof of working tests

 r11966@nc10 (orig r11025):  dhoss | 2009-08-04 01:00:57 +0100
 removed MooseX::Command::* stuff for now

 r11967@nc10 (orig r11026):  dhoss | 2009-08-04 01:01:43 +0100
 removed MooseX::App::CMD* stuff from ScriptRunner

 r11968@nc10 (orig r11027):  dhoss | 2009-08-04 01:22:27 +0100
 split helper into app generation helper and component generation helper (initial split, at least)

 r11976@nc10 (orig r11035):  dhoss | 2009-08-05 21:07:12 +0100
 had this stuff in the wrong branch, blech

 r12162@nc10 (orig r11221):  dhoss | 2009-08-23 21:32:34 +0100
 added command directory structure for MooseX::App::Cmd

 r12236@nc10 (orig r11295):  t0m | 2009-09-02 01:48:38 +0100
  r11288@t0mlaptop:  t0m | 2009-09-02 00:26:10 +0100
  Remove unused TestApp

 r12237@nc10 (orig r11296):  t0m | 2009-09-02 01:48:43 +0100
  r11289@t0mlaptop:  t0m | 2009-09-02 00:33:55 +0100
  Remove DBIC deploy script, this should not be in core runtime

 r12238@nc10 (orig r11297):  t0m | 2009-09-02 01:48:47 +0100
  r11290@t0mlaptop:  t0m | 2009-09-02 01:09:31 +0100
  Remove empty directories

 r12239@nc10 (orig r11298):  t0m | 2009-09-02 01:48:54 +0100
  r11291@t0mlaptop:  t0m | 2009-09-02 01:14:00 +0100
  Factor stuff out into a script role, clean up all the script code

 r12254@nc10 (orig r11313):  t0m | 2009-09-05 16:16:00 +0100
  r11320@tomas-dorans-macbook-pro:  t0m | 2009-09-05 12:38:54 +0100
  Fix passing correct key, re-add getopt trait as this is needed, my bad

 r12255@nc10 (orig r11314):  t0m | 2009-09-05 16:16:04 +0100
  r11321@tomas-dorans-macbook-pro:  t0m | 2009-09-05 12:42:20 +0100
  Make ScriptRunner include the lib path.

 r12256@nc10 (orig r11315):  t0m | 2009-09-05 16:16:08 +0100
  r11322@tomas-dorans-macbook-pro:  t0m | 2009-09-05 12:47:39 +0100
  Fix FastCGI script

 r12257@nc10 (orig r11316):  t0m | 2009-09-05 16:16:13 +0100
  r11323@tomas-dorans-macbook-pro:  t0m | 2009-09-05 12:48:58 +0100
  Fix CGI script

 r12258@nc10 (orig r11317):  t0m | 2009-09-05 16:16:15 +0100
  r11324@tomas-dorans-macbook-pro:  t0m | 2009-09-05 12:56:01 +0100
  Add a short TODO list to complete before this branch is merged

 r12259@nc10 (orig r11318):  t0m | 2009-09-05 16:16:20 +0100
  r11325@tomas-dorans-macbook-pro:  t0m | 2009-09-05 12:57:21 +0100
  Default run methods not required, can be provided by the role

 r12260@nc10 (orig r11319):  t0m | 2009-09-05 16:16:25 +0100
  r11326@tomas-dorans-macbook-pro:  t0m | 2009-09-05 13:00:17 +0100
  Documentation dinks

 r12261@nc10 (orig r11320):  t0m | 2009-09-05 16:16:30 +0100
  r11327@tomas-dorans-macbook-pro:  t0m | 2009-09-05 13:01:00 +0100
  Gawd, that is out of date

 r12262@nc10 (orig r11321):  t0m | 2009-09-05 16:16:33 +0100
  r11328@tomas-dorans-macbook-pro:  t0m | 2009-09-05 13:06:34 +0100
  More POD

 r12263@nc10 (orig r11322):  t0m | 2009-09-05 16:16:37 +0100
  r11329@tomas-dorans-macbook-pro:  t0m | 2009-09-05 13:08:41 +0100
  We need to depend on MX::Types, and ::StashChange not needed any more

 r12264@nc10 (orig r11323):  t0m | 2009-09-05 16:16:41 +0100
  r11330@tomas-dorans-macbook-pro:  t0m | 2009-09-05 13:09:11 +0100
  We also need autoclean

 r12265@nc10 (orig r11324):  t0m | 2009-09-05 16:16:48 +0100
  r11331@tomas-dorans-macbook-pro:  t0m | 2009-09-05 13:43:25 +0100
  Basic tests for ScriptRunner, more needed

 r12320@nc10 (orig r11379):  t0m | 2009-09-17 22:47:22 +0100
 Skeleton testapp for testing the args thrown to the run method by scripts
 r12321@nc10 (orig r11380):  t0m | 2009-09-17 23:10:46 +0100
 Meh, that shows what I mean. This can be done waaaay more elegantly by abstracting the testing logic..
 r12377@nc10 (orig r11436):  zts | 2009-09-27 20:12:39 +0100
 Further tests for Server script option parsing.
 Also, first pass at abstracting the test logic.  Currently very ugly.

 r12402@nc10 (orig r11461):  t0m | 2009-10-05 23:17:11 +0100
 And start the app correctly(ish) under the restarter - really not sure args are perserved correctly?
 r12908@nc10 (orig r11777):  dhoss | 2009-11-06 17:12:25 +0000
 fixed dev server options so that test now passes
 r12911@nc10 (orig r11780):  dhoss | 2009-11-06 17:25:35 +0000
 unfucked test server options and made test pass f'real this time
 r13011@nc10 (orig r11880):  t0m | 2009-11-18 00:51:29 +0000
 Beat somewhat into shape by comparing the old and new docs. Need to write basic tests for the other scripts.
 r13052@nc10 (orig r11921):  t0m | 2009-11-19 22:23:58 +0000
 Move to aggregate
 r13053@nc10 (orig r11922):  t0m | 2009-11-19 23:32:24 +0000
 Unified help display, at the cost of having lost the info about what you fucked up. Neither of these are particularly helpful, but this is at least uniform
 r13054@nc10 (orig r11923):  t0m | 2009-11-19 23:48:42 +0000
 Cleanup and some moar tests
 r13055@nc10 (orig r11924):  t0m | 2009-11-20 00:00:02 +0000
 More tests for help, proving it's still bork
 r13056@nc10 (orig r11925):  t0m | 2009-11-20 00:13:53 +0000
 Basic tests for fcgi script
 r13057@nc10 (orig r11926):  t0m | 2009-11-20 00:44:35 +0000
 Fix script_test.pl
 r13058@nc10 (orig r11927):  t0m | 2009-11-20 00:45:13 +0000
 Pass Pod coverage
 r13059@nc10 (orig r11928):  t0m | 2009-11-20 01:00:24 +0000
 Nested TAP and Test::Aggregate don't play nice together. It was cute, but screw it, sorry zts
 r13060@nc10 (orig r11929):  t0m | 2009-11-20 01:01:47 +0000
 Fugly test for myapp_test.pl. If someone fancies rewriting the IO redirection to be less gross then I loveyoulongtime
 r13061@nc10 (orig r11930):  t0m | 2009-11-20 01:07:04 +0000
 Update todo on this branch
 r13123@nc10 (orig r11992):  t0m | 2009-11-23 23:40:57 +0000
 Fix duplicate short options issue
 r13124@nc10 (orig r11993):  t0m | 2009-11-23 23:43:32 +0000
 Chomp trailing space
 r13125@nc10 (orig r11994):  t0m | 2009-11-23 23:49:10 +0000
 And do that in a way which actually works
 r13126@nc10 (orig r11995):  t0m | 2009-11-23 23:56:49 +0000
 Fix test
 r13127@nc10 (orig r11996):  t0m | 2009-11-24 00:15:45 +0000
 Add tests for the create script and fix the bugs that this shows up
 r13146@nc10 (orig r12015):  t0m | 2009-11-25 22:32:11 +0000
 Fix warnings from ScriptRunner
 r13147@nc10 (orig r12016):  t0m | 2009-11-25 22:51:28 +0000
 Fix big bug in test
 r13148@nc10 (orig r12017):  t0m | 2009-11-26 00:25:01 +0000
 Get useful help about which option you fucked up back
 r13149@nc10 (orig r12018):  t0m | 2009-11-26 00:35:31 +0000
 Remove most of the horrible
 r13150@nc10 (orig r12019):  t0m | 2009-11-26 01:02:52 +0000
 Tidy up help and TODO tests
 r13161@nc10 (orig r12030):  t0m | 2009-11-26 01:53:20 +0000
 Fix up docs
 r13162@nc10 (orig r12031):  t0m | 2009-11-26 02:23:00 +0000
 Factor restarter arg assembly out into it's own routine for ease of testing. Use $self->ARGV instead of $ARGV
 r13165@nc10 (orig r12034):  t0m | 2009-11-26 21:02:57 +0000
 Fix typo, bricas++, add simple test for restarter arguments
 r13175@nc10 (orig r12044):  t0m | 2009-11-26 23:40:27 +0000
 Pass app name into constructor
 r13185@nc10 (orig r12054):  t0m | 2009-11-27 02:08:33 +0000
 Bump version in runtime branch
 r13192@nc10 (orig r12061):  t0m | 2009-11-28 12:38:12 +0000
 Adding the files you need for the tests you've committed helps them pass, idiot :)
 r13194@nc10 (orig r12063):  rafl | 2009-11-29 14:00:12 +0000
 Depend on a new CMOP because we rely on its new load_class error messages.
 r13195@nc10 (orig r12064):  rafl | 2009-11-29 14:00:19 +0000
 Make follow_symlinks more consistent with the other restarter args.
 r13196@nc10 (orig r12065):  rafl | 2009-11-29 14:00:25 +0000
 Properly validate restart regexen.
 r13197@nc10 (orig r12066):  rafl | 2009-11-29 14:00:31 +0000
 Tidy up some attr definitions.
 r13198@nc10 (orig r12067):  rafl | 2009-11-29 14:00:38 +0000
 Port numbers need to be > 0.
 r13199@nc10 (orig r12068):  rafl | 2009-11-29 14:00:43 +0000
 Remove useless lexical.
 r13200@nc10 (orig r12069):  rafl | 2009-11-29 14:00:51 +0000
 Less trailing whitespace.
 r13201@nc10 (orig r12070):  rafl | 2009-11-29 15:33:48 +0000
 This is not a release.
 r13202@nc10 (orig r12071):  rafl | 2009-11-29 15:33:55 +0000
 Tidy things up a little and fix pod usage.

r12121@t0mlaptop (orig r12086):  t0m | 2009-11-30 22:59:15 +0000
Require new M::I
r12126@t0mlaptop (orig r12091):  t0m | 2009-12-01 00:09:19 +0000
 r12113@t0mlaptop (orig r12078):  t0m | 2009-11-30 18:25:57 +0000
 Branch for path_info fixes. This may be short lived, but worth doing..

 r12114@t0mlaptop (orig r12079):  t0m | 2009-11-30 18:26:34 +0000
 Commit miyagawa's fix for PATH_INFO decoding. I think that this also implies changes / fixes in the fcgi _fix_env stuff
 r12116@t0mlaptop (orig r12081):  t0m | 2009-11-30 20:44:16 +0000
 And yea, these test cases now pass
 r12118@t0mlaptop (orig r12083):  t0m | 2009-11-30 21:02:14 +0000
 I think the nginx hackery can just die with the new code in ::Engine::CGI
 r12119@t0mlaptop (orig r12084):  t0m | 2009-11-30 22:05:41 +0000
 Back out r12083, also clarify the docs - like this works for me now, and the bottom para seems the wrong way round...?
 r12122@t0mlaptop (orig r12087):  t0m | 2009-11-30 23:17:33 +0000
 Require new HTTP::Request::AsCGI
 r12124@t0mlaptop (orig r12089):  t0m | 2009-11-30 23:23:38 +0000
 Rewrite changelog entry to be more complete

r12127@t0mlaptop (orig r12092):  t0m | 2009-12-01 00:52:57 +0000
TODO out gshanks chained tests
r12128@t0mlaptop (orig r12093):  t0m | 2009-12-01 00:54:23 +0000
Bump deps and changelog for another dev release with new scripts and scary path resolving changes so I can have another call to test.

161 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/Component/ContextClosure.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/FastCGI.pm
lib/Catalyst/Engine/HTTP.pm
lib/Catalyst/Engine/HTTP/Restarter.pm [deleted file]
lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm [deleted file]
lib/Catalyst/Exception.pm
lib/Catalyst/Exception/Basic.pm [new file with mode: 0644]
lib/Catalyst/Exception/Detach.pm
lib/Catalyst/Exception/Go.pm
lib/Catalyst/Exception/Interface.pm [new file with mode: 0644]
lib/Catalyst/ROADMAP.pod
lib/Catalyst/Request.pm
lib/Catalyst/Response.pm
lib/Catalyst/Runtime.pm
lib/Catalyst/Script/CGI.pm [new file with mode: 0644]
lib/Catalyst/Script/Create.pm [new file with mode: 0644]
lib/Catalyst/Script/FastCGI.pm [new file with mode: 0644]
lib/Catalyst/Script/Server.pm [new file with mode: 0644]
lib/Catalyst/Script/Test.pm [new file with mode: 0644]
lib/Catalyst/ScriptRole.pm [new file with mode: 0644]
lib/Catalyst/ScriptRunner.pm [new file with mode: 0644]
lib/Catalyst/Stats.pm
lib/Catalyst/Test.pm
lib/Catalyst/Upgrading.pod
lib/Catalyst/Utils.pm
script/catalyst.pl
t/02pod.t [deleted file]
t/03podcoverage.t [deleted file]
t/04critic.t [deleted file]
t/aggregate/c3_appclass_bug.t [moved from t/c3_appclass_bug.t with 100% similarity]
t/aggregate/c3_mro.t [moved from t/c3_mro.t with 98% similarity]
t/aggregate/caf_backcompat.t [moved from t/caf_backcompat.t with 93% similarity]
t/aggregate/custom_live_component_controller_action_auto_doublebug.t [moved from t/custom_live_component_controller_action_auto_doublebug.t with 79% similarity]
t/aggregate/custom_live_path_bug.t [moved from t/custom_live_path_bug.t with 94% similarity]
t/aggregate/live_component_controller_action_auto.t
t/aggregate/live_component_controller_action_begin.t
t/aggregate/live_component_controller_action_chained.t
t/aggregate/live_component_controller_action_default.t
t/aggregate/live_component_controller_action_detach.t
t/aggregate/live_component_controller_action_forward.t
t/aggregate/live_component_controller_action_go.t
t/aggregate/live_component_controller_action_index.t
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_action_visit.t
t/aggregate/live_component_controller_anon.t [new file with mode: 0644]
t/aggregate/live_component_controller_attributes.t [moved from t/aggregate/live_component_controller_atttributes.t with 100% similarity]
t/aggregate/live_component_view_single.t
t/aggregate/live_engine_request_body.t
t/aggregate/live_engine_request_escaped_path.t
t/aggregate/live_engine_request_headers.t
t/aggregate/live_engine_request_remote_user.t
t/aggregate/meta_method_unneeded.t [moved from t/meta_method_unneeded.t with 95% similarity]
t/aggregate/unit_controller_actions.t [new file with mode: 0644]
t/aggregate/unit_controller_config.t [moved from t/unit_controller_config.t with 100% similarity]
t/aggregate/unit_controller_namespace.t [moved from t/unit_controller_namespace.t with 100% similarity]
t/aggregate/unit_core_action.t [new file with mode: 0644]
t/aggregate/unit_core_action_for.t
t/aggregate/unit_core_classdata.t [moved from t/unit_core_classdata.t with 98% similarity]
t/aggregate/unit_core_component.t [moved from t/unit_core_component.t with 99% similarity]
t/aggregate/unit_core_component_loading.t [moved from t/unit_core_component_loading.t with 81% similarity]
t/aggregate/unit_core_component_mro.t [moved from t/unit_core_component_mro.t with 81% similarity]
t/aggregate/unit_core_engine_fixenv-iis6.t [moved from t/unit_core_engine_fixenv-iis6.t with 100% similarity]
t/aggregate/unit_core_engine_fixenv-lighttpd.t [moved from t/unit_core_engine_fixenv-lighttpd.t with 100% similarity]
t/aggregate/unit_core_log.t [moved from t/unit_core_log.t with 91% similarity]
t/aggregate/unit_core_merge_config_hashes.t [moved from t/unit_core_merge_config_hashes.t with 84% similarity]
t/aggregate/unit_core_mvc.t [new file with mode: 0644]
t/aggregate/unit_core_path_to.t [moved from t/unit_core_path_to.t with 100% similarity]
t/aggregate/unit_core_plugin.t [moved from t/unit_core_plugin.t with 86% similarity]
t/aggregate/unit_core_script_cgi.t [new file with mode: 0644]
t/aggregate/unit_core_script_create.t [new file with mode: 0644]
t/aggregate/unit_core_script_fastcgi.t [new file with mode: 0644]
t/aggregate/unit_core_script_help.t [new file with mode: 0644]
t/aggregate/unit_core_script_server.t [new file with mode: 0644]
t/aggregate/unit_core_script_test.t [new file with mode: 0644]
t/aggregate/unit_core_scriptrunner.t [new file with mode: 0644]
t/aggregate/unit_core_setup.t [moved from t/unit_core_setup.t with 80% similarity]
t/aggregate/unit_core_setup_log.t [moved from t/unit_core_setup_log.t with 76% similarity]
t/aggregate/unit_core_setup_stats.t [moved from t/unit_core_setup_stats.t with 62% similarity]
t/aggregate/unit_core_uri_for.t [moved from t/unit_core_uri_for.t with 99% similarity]
t/aggregate/unit_core_uri_for_action.t
t/aggregate/unit_core_uri_with.t [moved from t/unit_core_uri_with.t with 100% similarity]
t/aggregate/unit_dispatcher_requestargs_restore.t [new file with mode: 0644]
t/aggregate/unit_load_catalyst_test.t [moved from t/unit_load_catalyst_test.t with 94% similarity]
t/aggregate/unit_metaclass_compat_extend_non_moose_controller.t [moved from t/unit_metaclass_compat_extend_non_moose_controller.t with 100% similarity]
t/aggregate/unit_metaclass_compat_non_moose.t [moved from t/unit_metaclass_compat_non_moose.t with 100% similarity]
t/aggregate/unit_metaclass_compat_non_moose_controller.t [new file with mode: 0644]
t/aggregate/unit_response.t [moved from t/unit_response.t with 100% similarity]
t/aggregate/unit_utils_env_value.t [moved from t/unit_utils_env_value.t with 95% similarity]
t/aggregate/unit_utils_prefix.t [moved from t/unit_utils_prefix.t with 93% similarity]
t/aggregate/unit_utils_request.t [moved from t/unit_utils_request.t with 90% similarity]
t/aggregate/utf8_content_length.t [new file with mode: 0644]
t/author/http-server.t [moved from t/optional_http-server.t with 61% similarity]
t/author/notabs.t [new file with mode: 0644]
t/author/pod.t [new file with mode: 0644]
t/author/podcoverage.t [new file with mode: 0644]
t/cdi_backcompat_plugin_accessor_override.t [deleted file]
t/custom_exception_class_simple.t [new file with mode: 0644]
t/deprecated.t
t/deprecated_appclass_action_warnings.t [new file with mode: 0644]
t/lib/ACLTestApp.pm [new file with mode: 0644]
t/lib/ACLTestApp/Controller/Root.pm [new file with mode: 0644]
t/lib/Catalyst/Plugin/Test/Deprecated.pm
t/lib/Catalyst/Plugin/Test/Plugin.pm
t/lib/Catalyst/Script/Bar.pm [new file with mode: 0644]
t/lib/Catalyst/Script/Baz.pm [new file with mode: 0644]
t/lib/Catalyst/Script/CompileTest.pm [new file with mode: 0644]
t/lib/DeprecatedActionsInAppClassTestApp.pm [new file with mode: 0644]
t/lib/PluginTestApp.pm
t/lib/PluginTestApp/Controller/Root.pm [new file with mode: 0644]
t/lib/ScriptTestApp/Script/Bar.pm [new file with mode: 0644]
t/lib/ScriptTestApp/Script/CompileTest.pm [new file with mode: 0644]
t/lib/ScriptTestApp/Script/Foo.pm [new file with mode: 0644]
t/lib/TestApp.pm
t/lib/TestApp/Action/TestMyAction.pm
t/lib/TestApp/Controller/Action/Chained.pm
t/lib/TestApp/Controller/Action/Chained/CaptureArgs.pm [new file with mode: 0644]
t/lib/TestApp/Controller/Action/Private.pm
t/lib/TestApp/Controller/Action/Streaming.pm
t/lib/TestApp/Controller/Anon.pm [new file with mode: 0644]
t/lib/TestApp/Controller/Dump.pm
t/lib/TestApp/Controller/Root.pm
t/lib/TestAppClassExceptionSimpleTest.pm [new file with mode: 0644]
t/lib/TestAppDoubleAutoBug.pm
t/lib/TestAppDoubleAutoBug/Controller/Root.pm [new file with mode: 0644]
t/lib/TestAppEncoding.pm [new file with mode: 0644]
t/lib/TestAppEncoding/Controller/Root.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/lib/TestAppPathBug.pm
t/lib/TestAppPluginWithConstructor.pm
t/lib/TestAppPluginWithConstructor/Controller/Root.pm [new file with mode: 0644]
t/lib/TestAppStats.pm
t/lib/TestAppStats/Controller/Root.pm [new file with mode: 0644]
t/lib/TestAppToTestScripts.pm [new file with mode: 0644]
t/lib/TestPluginWithConstructor.pm
t/live_component_controller_context_closure.t
t/live_fork.t
t/optional_http-server-restart.t
t/unit_core_mvc.t [deleted file]
t/unit_dispatcher_requestargs_restore.t [deleted file]
t/unit_metaclass_compat_non_moose_controller.t [deleted file]
t/unit_stats.t

diff --git a/Changes b/Changes
index 23532c2..a2ff652 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,8 +1,219 @@
 # This file documents the revision history for Perl extension Catalyst.
 
+5.80014_02 2009-12-01 00:55:23
+  Bug fixes:
+   - Fix reporting the wrong Content-Length if the response body is an
+     upgraded string. Strings mean the same thing whether or not they are
+     upgraded, may get upgraded even after they are encoded, and will
+     produce the same output either way, but bytes::length returns too big
+     values for upgraded strings containing characters >127
+   - Fix t/live_fork.t with bleadperl (RT#52100)
+   - Set $ENV{PATH_INFO} from $ENV{REQUEST_URI} combined with
+     $ENV{SCRIPT_NAME} if possible. This is many web servers always fully
+     decode PATH_INFO including URI reserved characters. This allows us to
+     tell foo%2cbar from foo%252cbar, and fixes issues with %2F in paths
+     being incorrectly decoded, resulting in too many path parts (rather
+     than 1 path part containing a /, on some web servers (at least nginx).
+     (RT#50082)
+   - Require new HTTP::Request::AsCGI so that it fully decodes $ENV{PATH_INFO}
+     in non CGI contexts. (RT#50082)
+
+  Refactoring / cleanups:
+   - NoTabs and Pod tests moved to t/author so that they're not run
+     (and then skipped) normally.
+
+  Documentation:
+    - Fix Pod nits in Catalyst::Response (RT#51818)
+
+5.80014_01 2009-11-22 20:01:23
+
+  Bug fixes:
+   - Filehandle now forced to binmode in CGI and FastCGI engines. This appears
+     to correct some UTF-8 issues, but may break people's code which relies
+     on the old behaviour.
+
+  Refactoring / cleanups:
+   - Plugins which inherit from Catalyst::Controller or Catalyst::Component
+     are deprecated and now issue warnings.
+
+5.80014 2009-11-21 02:51:14
+
+   Bug fixes:
+    - Require MooseX::MethodAttributes 0.17. This in turn requires new
+      MooseX::Types to stop warnings in Moose 0.91, and correctly supports
+      role combination of roles containing attributed methods.
+    - Catalyst::Dispatcher::dispatch_types no longer throws deprecated warnings
+      as there is no recommended alternative.
+    - Improved the suggested fix warning when component resolution uses regex
+      fallback for fully qualified component names.
+    - Catalyst::Test::local_request sets ->request on the response.
+    - Log flush moved to the end of setup so that roles and plugins which
+      hook setup_finalize can log things and have them appear in application
+      startup, rather than with the first hit.
+    - Require a newer version of LWP to avoid failing tests.
+    - Stop warnings when actions are forwarded to during dispatch.
+    - Remove warnings for using Catalyst::Dispatcher->dispatch_types as this is a
+      valid method to publicly call on the dispatcher.
+    - Args ($c->request->args) and CaptureArgs ($c->request->captrues)
+      passed to $c->uri_for with an action object ($c->action) will now
+      correctly round-trip when args or captures contain / as it is now
+      correctly uri encoded to %2F.
+
+  Documentation:
+    - Document no-args call to $c->uri_for.
+    - Document all top level application configuration parameters.
+    - Clarify how to fix actions in your application class (which is
+      deprecated and causes warnings).
+    - Pod fixes for ContextClosure.
+    - Fix documentation for go/visit to reference captures and arguments
+      in the correct order.
+    - Update $c->forward and $c->state documentation to address scalar
+      context.
+    - Pod fix in Catalyst::Request (RT#51490)
+    - Pod fixes to refer to ::Controller:: rather than ::C:: as the latter
+      is deprecated (RT#51489)
+
+  New features:
+    - Added disable_component_resolution_regex_fallback config option to
+      switch off (deprecated) regex fallback for component resolution.
+    - Added an nginx-specific behavior to the FastCGI engine to allow
+      proper PATH_INFO and SCRIPT_NAME processing for non-root applications
+    - Enable Catalyst::Utils::home() to find home within Dist::Zilla built
+      distributions
+    - Added the Catalyst::Exception::Interface role defining the interface
+      exception classes need to implement.
+    - Added Catalyst::Exception::Basic as a basic implementation of
+      Catalyst::Exception::Interface and made the existing exception classes
+      use it.
+
+  Refactoring / cleanups:
+    - Remove documentation for the case_sensitive setting
+    - Warning is now emitted at application startup if the case_sensitive
+      setting is turned on. This setting is not used by anyone, not
+      believed to be useful and adds unnecessary complexity to controllers
+      and the dispatcher. If you are using this setting and have good reasons
+      why it should stay then you need to be shouting, now.
+    - Writing to $c->req->body now fails as doing this never makes sense.
+
+5.80013 2009-09-17 11:07:04
+
+   Bug fixes:
+     - Preserve immutable_options when temporarily making a class mutable in
+       Catalyst::ClassData as this is needed by new Class::MOP.
+       This could have potentially caused issues when using the deprecated runtime
+       plugins feature in an application with plugins which define their own new
+       method.
+     - Require new Moose version and new versions of various dependencies
+       to avoid warnings from newest Moose release.
+     - Fix go / visit expecting captures and arguments in reverse order.
+
+  Documentation:
+     - Rework the $c->go documentation to make it more clear.
+     - Additional documentation in Catalyst::Upgrading covering more deprecation
+       warnings.
+
+  Refactoring / cleanups:
+     - Action methods in the application class are deprecated and applications
+       using them will now generate a warning at startup.
+     - The -short option has been removed from catalyst.pl, stopping new
+       applications from being generated using the ::[MVC]:: naming scheme as
+       this is deprecated and generates warnings. RT#49771
+
+5.80012 2009-09-09 19:09:09
+
+  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
+         (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'
+       - 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:
+       - 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
 
         - Add Catalyst::Component::ContextClosure as an easy way to create code
           references, that close over the context, without creating leaks.
 
-   Refactoring / cleanups:
+  Refactoring / cleanups:
         - Clean namespaces in Catalyst::Exception*.
         - Turn Catalyst::Exception into an actual class and make the throw
           method create instances of it. They can still be used as normal
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 3cec6d5..ba32c9d 100644 (file)
@@ -1,30 +1,42 @@
-use inc::Module::Install 0.87;
+use strict;
+use warnings;
+use inc::Module::Install 0.91;
+{   # Ensure that these get used - yes, M::I loads them for us, but if you're
+    # in author mode and don't have them installed, then the error is tres
+    # cryptic.
+    no warnings 'redefine';
+    use Module::Install::AuthorRequires;
+    use Module::Install::CheckConflicts;
+    use Module::Install::AuthorTests;
+}
 
-perl_version '5.008001';
+perl_version '5.008004';
 
 name 'Catalyst-Runtime';
 all_from 'lib/Catalyst/Runtime.pm';
 
-requires 'namespace::autoclean';
+requires 'List::MoreUtils';
+requires 'namespace::autoclean' => '0.09';
 requires 'namespace::clean';
+requires 'namespace::autoclean';
 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.12';
+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 'Carp';
 requires 'Class::C3::Adopt::NEXT' => '0.07';
 requires 'CGI::Simple::Cookie';
 requires 'Data::Dump';
-requires 'File::Modified';
 requires 'HTML::Entities';
 requires 'HTTP::Body'    => '1.04'; # makes uploadtmp work
 requires 'HTTP::Headers' => '1.64';
-requires 'HTTP::Request';
-requires 'HTTP::Response';
-requires 'HTTP::Request::AsCGI' => '0.8';
+requires 'HTTP::Request' => '5.814';
+requires 'HTTP::Response' => '5.813';
+requires 'HTTP::Request::AsCGI' => '1.0';
 requires 'LWP::UserAgent';
-requires 'Module::Pluggable' => '3.01';
+requires 'Module::Pluggable' => '3.9';
 requires 'Path::Class' => '0.09';
 requires 'Scalar::Util';
 requires 'Sub::Exporter';
@@ -36,12 +48,14 @@ requires 'URI' => '1.35';
 requires 'Task::Weaken';
 requires 'Text::Balanced'; # core in 5.8.x but mentioned for completeness
 requires 'MRO::Compat';
+requires 'MooseX::Getopt' => '0.25';
+requires 'MooseX::Types';
+requires 'MooseX::Types::Common::Numeric';
 requires 'String::RewritePrefix' => '0.004'; # Catalyst::Utils::resolve_namespace
 
-recommends 'B::Hooks::OP::Check::StashChange';
-
 test_requires 'Class::Data::Inheritable';
 test_requires 'Test::Exception';
+test_requires 'Test::More' => '0.88';
 
 # aggregate tests if AGGREGATE_TESTS is set and a recent Test::Aggregate and a Test::Simple it works with is available
 if ($ENV{AGGREGATE_TESTS} && can_use('Test::Simple', '0.88') && can_use('Test::Aggregate', '0.35_05')) {
@@ -53,7 +67,10 @@ else {
         grep { $_ ne 't/aggregate.t' }
         map  { glob } qw[t/*.t t/aggregate/*.t];
 }
+author_requires 'CatalystX::LeakChecker', '0.05'; # Skipped if this isn't installed
+author_requires 'File::Copy::Recursive'; # For http server test
 
+author_tests 't/author';
 author_requires(map {; $_ => 0 } qw(
   Test::NoTabs
   Test::Pod
@@ -98,6 +115,8 @@ EOF
 # NOTE - This is the version number of the _incompatible_ code,
 #        not the version number of the fixed version.
 my %conflicts = (
+    'Catalyst::Plugin::SubRequest' => '0.14',
+    'Catalyst::Model::Akismet' => '0.02',
     'Catalyst::Component::ACCEPT_CONTEXT' => '0.06',
     'Catalyst::Plugin::ENV' => '9999', # This plugin is just stupid, full stop
                                        # should have been a core fix.
@@ -112,7 +131,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',
@@ -123,6 +142,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);
 
@@ -135,10 +155,11 @@ sub darwin_check_no_resource_forks {
 
         # TAR on 10.4 wants COPY_EXTENDED_ATTRIBUTES_DISABLE
         # On 10.5 (Leopard) it wants COPYFILE_DISABLE
-        my $attr = $osx_ver eq '10.5' ? 'COPYFILE_DISABLE' : 'COPY_EXTENDED_ATTRIBUTES_DISABLE';
+         die("Oh, you got Ceiling Cat, snazzy. Please read the man page for tar or Google to find out if Apple renamed COPYFILE_DISABLE (it was COPY_EXTENDED_ATTRIBUTES_DISABLE originally) again and fix this Makefile.PL please?\n") if $osx_ver =~ /^10.7/;
+        my $attr = $osx_ver =~ /^10.(5|6)/  ? 'COPYFILE_DISABLE' : 'COPY_EXTENDED_ATTRIBUTES_DISABLE';
 
         makemaker_args(dist => { PREOP => qq{\@if [ "\$\$$attr" != "true" ]; then}.
-                                          qq{ echo "You must set the ENV variable $attr to true,"; }.
+                                          qq{ echo "You must set the ENV variable $attr to 'true',"; }.
                                           ' echo "to avoid getting resource forks in your dist."; exit 255; fi' });
     }
 }
diff --git a/TODO b/TODO
index 7d34863..4a2b319 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,36 +1,62 @@
-Known Bugs:
+# Known Bugs:
 
    - Bug ->go or ->visit causes actions which have Args or CaptureArgs called
      twice when called via ->go or ->visit.
 
      Test app: http://github.com/bobtfish/catalyst-app-bug-go_chain/tree/master
 
-Compatibility warnings to add:
+   - Bricas' Exception blog post
 
-   - $self->config should warn as config should only ever be called as a
-     class method.
+     http://bricas.vox.com/library/post/catalyst-exceptionclass.html
 
-Proposed functionality / feature additions:
+     Broken by recent exception refactoring
 
-    - Log setup needs to be less lame, so Catalyst::Plugin::Log::* can die
-      in a fire. Having $c->log_class would be a good start. kane volunteered
-      to do some of this.
+# Compatibility warnings to add:
 
-      Simple example: Catalyst::Plugin::Log::Colorful should just be a
-      subclass of Catalyst::Log, no ::Plugin:: needed.
+  - $self->config should warn as config should only ever be called as a
+    class method (TESTS).
 
-      See also: Catalyst::Plugin::Log::Dispatch and
-      http://github.com/willert/catalyst-plugin-log4perl-simple/tree
+# Proposed functionality / feature additions:
 
-TODO for brach namespace_handling_refactor:
+## Log setup needs to be less lame
 
-- refactor code in
-  * Catalyst::Dispatcher::get_containers           # No Idea
-  * Catalyst::Dispatcher::dispatch_type            # DONE
+So Catalyst::Plugin::Log::* can die
+in a fire. Having $c->log_class would be a good start. kane volunteered
+to do some of this.
 
-  * Catalyst::Controller::_parse_ActionClass_attr  # DONE
-  * Catalyst::Dispatcher::_load_dispatch_types     # DONE
-  * Catalyst::setup_plugins                        # DONE
-  to use the same namespacing method
+Simple example: Catalyst::Plugin::Log::Colorful should just be a
+subclass of Catalyst::Log, no ::Plugin:: needed.
 
-- Ok, so can you add tests for ->config(actions => { foo => { ActionClass => '+Bar' }});
+See also: Catalyst::Plugin::Log::Dispatch and
+http://github.com/willert/catalyst-plugin-log4perl-simple/tree
+
+# REFACTORING
+
+##  The horrible hack for plugin setup - replacing it:
+
+ * Have a look at the Devel::REPL BEFORE_PLUGIN stuff
+   I wonder if what we need is that combined with plugins-as-roles
+
+## App / ctx split:
+
+  NOTE - these are notes that t0m thought up after doing back compat for
+         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 :)
+
+  - Eliminate actions in MyApp from the main test suite
+  - Uncomment warning in C::C::register_action_methods, add tests it works
+    by mocking out the logging..
+  - Remove MyApp @ISA controller (ask metaclass if it has attributes, and if
+                                  so you need back compat :/)
+  - Make Catalyst::Context, move the per request stuff in there, handles from
+    main app class to delegate
+  - Make an instance of the app class which is a global variable
+  - Make new instance of the context class, not the app class per-request
+  - Remove the components as class data, move to instance data on the app
+    class (you probably have to do this for _all_ the class data, good luck!)
+  - Make it possible for users to spin up different instances of the app class
+    (with different config etc each)
+  - 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 4db4a69..9e74bee 100644 (file)
@@ -4,7 +4,6 @@ use Moose;
 use Moose::Meta::Class ();
 extends 'Catalyst::Component';
 use Moose::Util qw/find_meta/;
-use bytes;
 use B::Hooks::EndOfScope ();
 use Catalyst::Exception;
 use Catalyst::Exception::Detach;
@@ -27,11 +26,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 +78,7 @@ __PACKAGE__->stats_class('Catalyst::Stats');
 
 # Remember to update this in Catalyst::Runtime as well!
 
-our $VERSION = '5.80007';
+our $VERSION = '5.80014_02';
 
 {
     my $dev_version = $VERSION =~ /_\d{2}$/;
@@ -335,9 +335,11 @@ call to forward.
     $c->forward(qw/MyApp::Model::DBIC::Foo do_stuff/);
     $c->forward('MyApp::View::TT');
 
-Note that forward implies an C<<eval { }>> around the call (actually
-C<execute> does), thus de-fatalizing all 'dies' within the called
-action. If you want C<die> to propagate you need to do something like:
+Note that L<< forward|/"$c->forward( $action [, \@arguments ] )" >> implies
+an C<< eval { } >> around the call (actually
+L<< execute|/"$c->execute( $class, $coderef )" >> does), thus de-fatalizing
+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;
@@ -346,6 +348,21 @@ 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, 
+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, 
+or stash it like so:
+
+    $c->stash->{array} = \@array;
+
+and access it from the stash.
 
 =cut
 
@@ -357,8 +374,8 @@ sub forward { my $c = shift; no warnings 'recursion'; $c->dispatcher->forward( $
 
 =head2 $c->detach()
 
-The same as C<forward>, but doesn't return to the previous action when
-processing is finished.
+The same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, but
+doesn't return to the previous action when processing is finished.
 
 When called with no arguments it escapes the processing chain entirely.
 
@@ -370,23 +387,27 @@ sub detach { my $c = shift; $c->dispatcher->detach( $c, @_ ) }
 
 =head2 $c->visit( $class, $method, [, \@captures, \@arguments ] )
 
-Almost the same as C<forward>, but does a full dispatch, instead of just
-calling the new C<$action> / C<$class-E<gt>$method>. This means that C<begin>,
-C<auto> and the method you go to are called, just like a new request.
+Almost the same as L<< forward|/"$c->forward( $action [, \@arguments ] )" >>,
+but does a full dispatch, instead of just calling the new C<$action> /
+C<< $class->$method >>. This means that C<begin>, C<auto> and the method
+you go to are called, just like a new request.
 
 In addition both C<< $c->action >> and C<< $c->namespace >> are localized.
-This means, for example, that $c->action methods such as C<name>, C<class> and
-C<reverse> return information for the visited action when they are invoked
-within the visited action.  This is different from the behavior of C<forward>
-which continues to use the $c->action object from the caller action even when
+This means, for example, that C<< $c->action >> methods such as
+L<name|Catalyst::Action/name>, L<class|Catalyst::Action/class> and
+L<reverse|Catalyst::Action/reverse> return information for the visited action
+when they are invoked within the visited action.  This is different from the
+behavior of L<< forward|/"$c->forward( $action [, \@arguments ] )" >>, which
+continues to use the $c->action object from the caller action even when
 invoked from the callee.
 
-C<$c-E<gt>stash> is kept unchanged.
+C<< $c->stash >> is kept unchanged.
 
-In effect, C<visit> allows you to "wrap" another action, just as it
-would have been called by dispatching from a URL, while the analogous
-C<go> allows you to transfer control to another action as if it had
-been reached directly from a URL.
+In effect, L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >>
+allows you to "wrap" another action, just as it would have been called by
+dispatching from a URL, while the analogous
+L<< go|/"$c->go( $action [, \@captures, \@arguments ] )" >> allows you to
+transfer control to another action as if it had been reached directly from a URL.
 
 =cut
 
@@ -396,12 +417,15 @@ sub visit { my $c = shift; $c->dispatcher->visit( $c, @_ ) }
 
 =head2 $c->go( $class, $method, [, \@captures, \@arguments ] )
 
-Almost the same as C<detach>, but does a full dispatch like C<visit>,
-instead of just calling the new C<$action> /
-C<$class-E<gt>$method>. This means that C<begin>, C<auto> and the
-method you visit are called, just like a new request.
-
-C<$c-E<gt>stash> is kept unchanged.
+The relationship between C<go> and 
+L<< visit|/"$c->visit( $action [, \@captures, \@arguments ] )" >> is the same as
+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,
+with localized C<< $c->action >> and C<< $c->namespace >>. Like C<detach>,
+C<go> escapes the processing of the current request chain on completion, and
+does not return to its caller.
 
 =cut
 
@@ -480,7 +504,9 @@ 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.
 
 =head2 $c->clear_errors
 
@@ -525,6 +551,10 @@ sub _comp_names_search_prefixes {
     # if we were given a regexp to search against, we're done.
     return if ref $name;
 
+    # skip regexp fallback if configured
+    return
+        if $appclass->config->{disable_component_resolution_regex_fallback};
+
     # regexp fallback
     $query  = qr/$name/i;
     @result = grep { $eligible{ $_ } =~ m{$query} } keys %eligible;
@@ -542,7 +572,8 @@ sub _comp_names_search_prefixes {
            (join '", "', @result) . "'. Relying on regexp fallback behavior for " .
            "component resolution is unreliable and unsafe.";
         my $short = $result[0];
-        $short =~ s/.*?Model:://;
+        # remove the component namespace prefix
+        $short =~ s/.*?(Model|Controller|View):://;
         my $shortmess = Carp::shortmess('');
         if ($shortmess =~ m#Catalyst/Plugin#) {
            $msg .= " You probably need to set '$short' instead of '${name}' in this " .
@@ -551,7 +582,7 @@ sub _comp_names_search_prefixes {
            $msg .= " You probably need to set '$short' instead of '${name}' in this " .
               "component's config";
         } else {
-           $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}({'${name}'}), " .
+           $msg .= " You probably meant \$c->${warn_for}('$short') instead of \$c->${warn_for}('${name}'), " .
               "but if you really wanted to search, pass in a regexp as the argument " .
               "like so: \$c->${warn_for}(qr/${name}/)";
         }
@@ -639,7 +670,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;
@@ -652,14 +683,14 @@ 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/);
 
     if( $rest ) {
         $c->log->warn( Carp::shortmess('Calling $c->model() will return a random model unless you specify one of:') );
-        $c->log->warn( '* $c->config->{default_model} # the name of the default model to use' );
+        $c->log->warn( '* $c->config(default_model => "the name of the default model to use")' );
         $c->log->warn( '* $c->stash->{current_model} # the name of the model to use for this request' );
         $c->log->warn( '* $c->stash->{current_model_instance} # the instance of the model to use for this request' );
         $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
@@ -693,6 +724,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;
@@ -705,14 +737,14 @@ 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/);
 
     if( $rest ) {
         $c->log->warn( 'Calling $c->view() will return a random view unless you specify one of:' );
-        $c->log->warn( '* $c->config->{default_view} # the name of the default view to use' );
+        $c->log->warn( '* $c->config(default_view => "the name of the default view to use")' );
         $c->log->warn( '* $c->stash->{current_view} # the name of the view to use for this request' );
         $c->log->warn( '* $c->stash->{current_view_instance} # the instance of the view to use for this request' );
         $c->log->warn( 'NB: in version 5.81, the "random" behavior will not work at all.' );
@@ -767,6 +799,12 @@ should be used instead.
 If C<$name> is a regexp, a list of components matched against the full
 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
 
 sub component {
@@ -818,11 +856,11 @@ Returns or takes a hashref containing the application's configuration.
 
     __PACKAGE__->config( { db => 'dsn:SQLite:foo.db' } );
 
-You can also use a C<YAML>, C<XML> or C<Config::General> config file
-like myapp.conf in your applications home directory. See
+You can also use a C<YAML>, C<XML> or L<Config::General> config file
+like C<myapp.conf> in your applications home directory. See
 L<Catalyst::Plugin::ConfigLoader>.
 
-=head3 Cascading configuration.
+=head3 Cascading configuration
 
 The config method is present on all Catalyst components, and configuration
 will be merged when an application is started. Configuration loaded with
@@ -918,7 +956,7 @@ Returns the engine instance. See L<Catalyst::Engine>.
 Merges C<@path> with C<< $c->config->{home} >> and returns a
 L<Path::Class::Dir> object. Note you can usually use this object as
 a filename, but sometimes you will have to explicitly stringify it
-yourself by calling the C<<->stringify>> method.
+yourself by calling the C<< ->stringify >> method.
 
 For example:
 
@@ -1106,7 +1144,6 @@ EOF
         my $name = $class->config->{name} || 'Application';
         $class->log->info("$name powered by Catalyst $Catalyst::VERSION");
     }
-    $class->log->_flush() if $class->log->can('_flush');
 
     # Make sure that the application class becomes immutable at this point,
     B::Hooks::EndOfScope::on_scope_end {
@@ -1126,11 +1163,21 @@ EOF
                 . "Class::Accessor(::Fast)?\nPlease pass "
                 . "(replace_constructor => 1)\nwhen making your class immutable.\n";
         }
-        $meta->make_immutable(replace_constructor => 1)
-            unless $meta->is_immutable;
+        $meta->make_immutable(
+            replace_constructor => 1,
+        ) unless $meta->is_immutable;
     };
 
+    if ($class->config->{case_sensitive}) {
+        $class->log->warn($class . "->config->{case_sensitive} is set.");
+        $class->log->warn("This setting is deprecated and planned to be removed in Catalyst 5.81.");
+    }
+
     $class->setup_finalize;
+    # Should be the last thing we do so that user things hooking
+    # setup_finalize can log..
+    $class->log->_flush() if $class->log->can('_flush');
+    return 1; # Explicit return true as people have __PACKAGE__->setup as the last thing in their class. HATE.
 }
 
 
@@ -1158,40 +1205,63 @@ sub setup_finalize {
     $class->setup_finished(1);
 }
 
-=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
-
-=head2 $c->uri_for( $path, @args?, \%query_values? )
-
-=over
-
-=item $action
-
-A Catalyst::Action object representing the Catalyst action you want to
-create a URI for. To get one for an action in the current controller,
-use C<< $c->action('someactionname') >>. To get one from different
-controller, fetch the controller using C<< $c->controller() >>, then
-call C<action_for> on it.
+=head2 $c->uri_for( $path?, @args?, \%query_values? )
 
-You can maintain the arguments captured by an action (e.g.: Regex, Chained)
-using C<< $c->req->captures >>.
+=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
 
-  # For the current action
-  $c->uri_for($c->action, $c->req->captures);
+Constructs an absolute L<URI> object based on the application root, the
+provided path, and the additional arguments and query parameters provided.
+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 ) >>. 
+
+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
+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.
+
+If the first argument is a L<Catalyst::Action> it represents an action which
+will have its path resolved using C<< $c->dispatcher->uri_for_action >>. The
+optional C<\@captures> argument (an arrayref) allows passing the captured
+variables that are needed to fill in the paths of Chained and Regex actions;
+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
+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->req->args }, $c->req->params);
 
   # For the Foo action in the Bar controller
-  $c->uri_for($c->controller('Bar')->action_for('Foo'), $c->req->captures);
+  $c->uri_for($c->controller('Bar')->action_for('Foo'));
 
-=back
+  # Path to a static resource
+  $c->uri_for('/static/images/logo.png');
 
 =cut
 
 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)
-                         : [] );
+        my $captures = [ map { s|/|%2F|; $_; }
+                        ( scalar @args && ref $args[0] eq 'ARRAY'
+                         ? @{ shift(@args) }
+                         : ()) ];
         my $action = $path;
         $path = $c->dispatcher->uri_for_action($action, $captures);
         if (not defined $path) {
@@ -1209,6 +1279,7 @@ sub uri_for {
 
     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);
 
@@ -1541,9 +1612,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}++;
@@ -1571,9 +1642,10 @@ sub _stats_start_execute {
 
     # is this a root-level call or a forwarded call?
     if ( $callsub =~ /forward$/ ) {
+        my $parent = $c->stack->[-1];
 
         # forward, locate the caller
-        if ( my $parent = $c->stack->[-1] ) {
+        if ( exists $c->counter->{"$parent"} ) {
             $c->stats->profile(
                 begin  => $action,
                 parent => "$parent" . $c->counter->{"$parent"},
@@ -1606,25 +1678,6 @@ sub _stats_finish_execute {
     $c->stats->profile( end => $info );
 }
 
-=head2 $c->_localize_fields( sub { }, \%keys );
-
-=cut
-
-#Why does this exist? This is no longer safe and WILL NOT WORK.
-# it doesnt seem to be used anywhere. can we remove it?
-sub _localize_fields {
-    my ( $c, $localized, $code ) = ( @_ );
-
-    my $request = delete $localized->{request} || {};
-    my $response = delete $localized->{response} || {};
-
-    local @{ $c }{ keys %$localized } = values %$localized;
-    local @{ $c->request }{ keys %$request } = values %$request;
-    local @{ $c->response }{ keys %$response } = values %$response;
-
-    $code->();
-}
-
 =head2 $c->finalize
 
 Finalizes the request.
@@ -1741,7 +1794,7 @@ sub finalize_headers {
         }
         else {
             # everything should be bytes at this point, but just in case
-            $response->content_length( bytes::length( $response->body ) );
+            $response->content_length( length( $response->body ) );
         }
     }
 
@@ -1878,7 +1931,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;
         }
     }
@@ -2453,7 +2506,7 @@ Reads a chunk of data from the request body. This method is designed to
 be used in a while loop, reading C<$maxlength> bytes on every call.
 C<$maxlength> defaults to the size of the request if not specified.
 
-You have to set C<< MyApp->config->{parse_on_demand} >> to use this
+You have to set C<< MyApp->config(parse_on_demand => 1) >> to use this
 directly.
 
 Warning: If you use read(), Catalyst will not process the body,
@@ -2490,40 +2543,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.
+
+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.
 
-All components found will also have any
-L<Devel::InnerPackage|inner packages> 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.
+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 ) {
 
@@ -2532,30 +2577,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);
@@ -2569,16 +2660,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 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->{catalyst_component_name} = $component;
 
     my $instance = eval { $component->COMPONENT( $class, $config ); };
 
@@ -2862,7 +2949,8 @@ the plugin name does not begin with C<Catalyst::Plugin::>.
         my $class = ref $proto || $proto;
 
         Class::MOP::load_class( $plugin );
-
+        $class->log->warn( "$plugin inherits from 'Catalyst::Component' - this is decated and will not work in 5.81" )
+            if $plugin->isa( 'Catalyst::Component' );
         $proto->_plugins->{$plugin} = 1;
         unless ($instant) {
             no strict 'refs';
@@ -2953,23 +3041,80 @@ messages in template systems.
 
 sub version { return $Catalyst::VERSION }
 
-=head1 INTERNAL ACTIONS
+=head1 CONFIGURATION
 
-Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
-C<_ACTION>, and C<_END>. These are by default not shown in the private
-action table, but you can make them visible with a config parameter.
+There are a number of 'base' config variables which can be set:
+
+=over
+
+=item *
+
+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.
+
+=item *
+
+C<disable_component_resolution_regex_fallback> - Turns
+off the deprecated component resolution functionality so
+that if any of the component methods (e.g. C<< $c->controller('Foo') >>)
+are called then regex search will not be attempted on string values and
+instead C<undef> will be returned.
+
+=item *
+
+C<home> - The application home directory. In an uninstalled application,
+this is the top level application directory. In an installed application,
+this will be the directory containing C<< MyApp.pm >>.
+
+=item *
+
+C<ignore_frontend_proxy> - See L</PROXY SUPPORT>
+
+=item *
+
+C<name> - The name of the application in debug messages and the debug and
+welcome screens
+
+=item *
+
+C<parse_on_demand> - The request body (for example file uploads) will not be parsed
+until it is accessed. This allows you to (for example) check authentication (and reject
+the upload) before actually recieving all the data. See L</ON-DEMAND PARSER>
+
+=item *
+
+C<root> - The root directory for templates. Usually this is just a
+subdirectory of the home directory, but you can set it to change the
+templates to a different directory.
+
+=item *
 
-    MyApp->config->{show_internal_actions} = 1;
+C<search_extra> - Array reference passed to Module::Pluggable to for additional
+namespaces from which components will be loaded (and constructed and stored in
+C<< $c->components >>).
 
-=head1 CASE SENSITIVITY
+=item *
 
-By default Catalyst is not case sensitive, so C<MyApp::C::FOO::Bar> is
-mapped to C</foo/bar>. You can activate case sensitivity with a config
-parameter.
+C<show_internal_actions> - If true, causes internal actions such as C<< _DISPATCH >>
+to be shown in hit debug tables in the test server.
 
-    MyApp->config->{case_sensitive} = 1;
+=item *
 
-This causes C<MyApp::C::Foo::Bar> to map to C</Foo/Bar>.
+C<using_frontend_proxy> - See L</PROXY SUPPORT>.
+
+=back
+
+=head1 INTERNAL ACTIONS
+
+Catalyst uses internal actions like C<_DISPATCH>, C<_BEGIN>, C<_AUTO>,
+C<_ACTION>, and C<_END>. These are by default not shown in the private
+action table, but you can make them visible with a config parameter.
+
+    MyApp->config(show_internal_actions => 1);
 
 =head1 ON-DEMAND PARSER
 
@@ -2977,7 +3122,7 @@ The request body is usually parsed at the beginning of a request,
 but if you want to handle input yourself, you can enable on-demand
 parsing with a config parameter.
 
-    MyApp->config->{parse_on_demand} = 1;
+    MyApp->config(parse_on_demand => 1);
 
 =head1 PROXY SUPPORT
 
@@ -2998,6 +3143,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
@@ -3005,11 +3162,11 @@ frontend proxy server(s) on different machines, you will need to set a
 configuration option to tell Catalyst to read the proxied data from the
 headers.
 
-    MyApp->config->{using_frontend_proxy} = 1;
+    MyApp->config(using_frontend_proxy => 1);
 
 If you do not wish to use the proxy support at all, you may set:
 
-    MyApp->config->{ignore_frontend_proxy} = 1;
+    MyApp->config(ignore_frontend_proxy => 1);
 
 =head1 THREAD SAFETY
 
@@ -3046,7 +3203,7 @@ Wiki:
 
 =head2 L<Catalyst::Manual> - The Catalyst Manual
 
-=head2 L<Catalyst::Component>, L<Catalyst::Base> - Base classes for components
+=head2 L<Catalyst::Component>, L<Catalyst::Controller> - Base classes for components
 
 =head2 L<Catalyst::Engine> - Core engine
 
@@ -3068,9 +3225,11 @@ abw: Andy Wardley
 
 acme: Leon Brocard <leon@astray.com>
 
+abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
+
 Andrew Bramble
 
-Andrew Ford
+Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
 
 Andrew Ruthven
 
@@ -3086,8 +3245,18 @@ 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
 
+dhoss: Devin Austin <dhoss@cpan.org>
+
 dkubb: Dan Kubb <dan.kubb-cpan@onautopilot.com>
 
 Drew Taylor
@@ -3098,16 +3267,26 @@ 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
 
+groditi: Guillermo Roditi <groditi@gmail.com>
+
+hobbs: Andrew Rodland <andrew@cleverdomain.org>
+
 ilmari: Dagfinn Ilmari MannsÃ¥ker <ilmari@ilmari.org>
 
 jcamacho: Juan Camacho
 
+jester: Jesse Sheidlower C<jester@panix.com>
+
 jhannah: Jay Hannah <jay@jays.net>
 
 Jody Belka
@@ -3116,6 +3295,12 @@ 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>
 
 miyagawa: Tatsuhiko Miyagawa <miyagawa@bulknews.net>
@@ -3144,16 +3329,22 @@ rafl: Florian Ragwitz <rafl@debian.org>
 
 random: Roland Lammel <lammel@cpan.org>
 
-sky: Arthur Bergman
+Robert Sedlacek C<< <rs@474.at> >>
 
-the_jester: Jesse Sheidlower
+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 cd2d008..87b37fd 100644 (file)
@@ -8,6 +8,8 @@ Catalyst::Action - Catalyst Action
 
     <form action="[%c.uri_for(c.action)%]">
 
+    $c->forward( $action->private_path );
+
 =head1 DESCRIPTION
 
 This class represents a Catalyst Action. You can access the object for the
@@ -28,6 +30,13 @@ has 'reverse' => (is => 'rw');
 has attributes => (is => 'rw');
 has name => (is => 'rw');
 has code => (is => 'rw');
+has private_path => (
+  reader => 'private_path',
+  isa => 'Str',
+  lazy => 1,
+  required => 1,
+  default => sub { '/'.shift->reverse },
+);
 
 use overload (
 
@@ -46,8 +55,6 @@ use overload (
 
 no warnings 'recursion';
 
-#__PACKAGE__->mk_accessors(qw/class namespace reverse attributes name code/);
-
 sub dispatch {    # Execute ourselves against a context
     my ( $self, $c ) = @_;
     return $c->execute( $self->class, $self );
@@ -75,7 +82,7 @@ sub compare {
     my ($a1_args) = @{ $a1->attributes->{Args} || [] };
     my ($a2_args) = @{ $a2->attributes->{Args} || [] };
 
-    $_ = looks_like_number($_) ? $_ : ~0 
+    $_ = looks_like_number($_) ? $_ : ~0
         for $a1_args, $a2_args;
 
     return $a1_args <=> $a2_args;
@@ -96,7 +103,9 @@ and so on. This determines how the action is dispatched to.
 
 =head2 class
 
-Returns the class name where this action is defined.
+Returns the name of the component where this action is defined.
+Derived by calling the L<Catalyst::Component/catalyst_component_name|catalyst_component_name>
+method on each component.
 
 =head2 code
 
@@ -104,7 +113,7 @@ Returns a code reference to this action.
 
 =head2 dispatch( $c )
 
-Dispatch this action against a context
+Dispatch this action against a context.
 
 =head2 execute( $controller, $c, @args )
 
@@ -129,13 +138,18 @@ Returns the private namespace this action lives in.
 
 Returns the private path for this action.
 
+=head2 private_path
+
+Returns absolute private path for this action. Unlike C<reverse>, the
+C<private_path> of an action is always suitable for passing to C<forward>.
+
 =head2 name
 
-returns the sub name of this action.
+Returns the sub name of this action.
 
 =head2 meta
 
-Provided by Moose
+Provided by Moose.
 
 =head1 AUTHORS
 
index f252f05..89cc1fd 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;
 
@@ -49,13 +49,15 @@ sub mk_classdata {
     unless $meta->isa('Class::MOP::Class');
 
   my $was_immutable = $meta->is_immutable;
+  my %immutable_options = $meta->immutable_options;
+
   $meta->make_mutable if $was_immutable;
 
   my $alias = "_${attribute}_accessor";
   $meta->add_method($alias, $accessor);
   $meta->add_method($attribute, $accessor);
 
-  $meta->make_immutable if $was_immutable;
+  $meta->make_immutable(%immutable_options) if $was_immutable;
 
   $class->$attribute($_[2]) if(@_ > 2);
   return $accessor;
index f0a6d60..fe0ef6f 100644 (file)
@@ -60,6 +60,18 @@ component loader with config() support and a process() method placeholder.
 __PACKAGE__->mk_classdata('_plugins');
 __PACKAGE__->mk_classdata('_config');
 
+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
+# 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);
+    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 {
     my $class = shift;
     my $args = {};
@@ -85,23 +97,24 @@ sub BUILDARGS {
 }
 
 sub COMPONENT {
-    my ( $self, $c ) = @_;
+    my ( $class, $c ) = @_;
 
     # Temporary fix, some components does not pass context to constructor
     my $arguments = ( ref( $_[-1] ) eq 'HASH' ) ? $_[-1] : {};
-    if( my $next = $self->next::can ){
-      my $class = blessed $self || $self;
+    if ( my $next = $class->next::can ) {
       my ($next_package) = Class::MOP::get_code_info($next);
       warn "There is a COMPONENT method resolving after Catalyst::Component in ${next_package}.\n";
       warn "This behavior can no longer be supported, and so your application is probably broken.\n";
       warn "Your linearized isa hierarchy is: " . join(', ', @{ mro::get_linear_isa($class) }) . "\n";
       warn "Please see perldoc Catalyst::Upgrading for more information about this issue.\n";
     }
-    return $self->new($c, $arguments);
+    return $class->new($c, $arguments);
 }
 
 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]} };
@@ -157,9 +170,10 @@ If this method is present (as it is on all Catalyst::Component subclasses,
 it is called by Catalyst during setup_components with the application class
 as $c and any config entry on the application for this component (for example,
 in the case of MyApp::Controller::Foo this would be
-MyApp->config->{'Controller::Foo'}). The arguments are expected to be a
-hashref and are merged with the __PACKAGE__->config hashref before calling
-->new to instantiate the component.
+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.
 
 You can override it in your components to do custom instantiation, using
 something like this:
index 23e1381..18d09b7 100644 (file)
@@ -22,7 +22,7 @@ Catalyst::Component::ContextClosure - Moose Role for components which need to cl
 
     package MyApp::Controller::Foo;
     use Moose;
-    use namespace::autoclean;
+    use namespace::clean -except => 'meta';
     BEGIN {
         extends 'Catalyst::Controller';
         with 'Catalyst::Component::ContextClosure';
@@ -33,7 +33,7 @@ Catalyst::Component::ContextClosure - Moose Role for components which need to cl
         $ctx->stash(a_closure => $self->make_context_closure(sub {
             my ($ctx) = @_;
             $ctx->response->body('body set from closure');
-        }, $ctx);
+        }, $ctx));
     }
 
 =head1 DESCRIPTION
index aca0b1c..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(ref($self) || $self, $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." )
@@ -190,13 +194,13 @@ sub get_action_methods {
         @methods,
         map {
             $meta->find_method_by_name($_)
-              || confess( 'Action "' 
+              || confess( 'Action "'
                   . $_
                   . '" is not available from controller '
                   . ( ref $self ) )
           } keys %{ $self->_controller_actions }
     ) if ( ref $self );
-    return @methods;
+    return uniq @methods;
 }
 
 
@@ -207,10 +211,18 @@ sub register_actions {
 
 sub register_action_methods {
     my ( $self, $c, @methods ) = @_;
-    my $class = ref $self || $self;
+    my $class = $self->catalyst_component_name;
     #this is still not correct for some reason.
     my $namespace = $self->action_namespace($c);
 
+    # FIXME - fugly
+    if (!blessed($self) && $self eq $c && scalar(@methods)) {
+        my @really_bad_methods = grep { ! /^_(DISPATCH|BEGIN|AUTO|ACTION|END)$/ } map { $_->name } @methods;
+        if (scalar(@really_bad_methods)) {
+            $c->log->warn("Action methods (" . join(', ', @really_bad_methods) . ") found defined in your application class, $self. This is deprecated, please move them into a Root controller.");
+        }
+    }
+
     foreach my $method (@methods) {
         my $name = $method->name;
         my $attributes = $method->attributes;
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 ec62c1f..d82dfe1 100644 (file)
@@ -29,7 +29,7 @@ our @POSTLOAD = qw/Default/;
 
 # Note - see back-compat methods at end of file.
 has _tree => (is => 'rw', builder => '_build__tree');
-has _dispatch_types => (is => 'rw', default => sub { [] }, required => 1, lazy => 1);
+has dispatch_types => (is => 'rw', default => sub { [] }, required => 1, lazy => 1);
 has _registered_dispatch_types => (is => 'rw', default => sub { {} }, required => 1, lazy => 1);
 has _method_action_class => (is => 'rw', default => 'Catalyst::Action');
 has _action_hash => (is => 'rw', required => 1, lazy => 1, default => sub { {} });
@@ -131,7 +131,7 @@ sub _command2action {
     my (@args, @captures);
 
     if ( ref( $extra_params[-2] ) eq 'ARRAY' ) {
-        @captures = @{ pop @extra_params };
+        @captures = @{ splice @extra_params, -2, 1 };
     }
 
     if ( ref( $extra_params[-1] ) eq 'ARRAY' ) {
@@ -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}
                 ),
             }
         );
@@ -372,7 +372,7 @@ sub prepare_action {
         # Check out dispatch types to see if any will handle the path at
         # this level
 
-        foreach my $type ( @{ $self->_dispatch_types } ) {
+        foreach my $type ( @{ $self->dispatch_types } ) {
             last DESCEND if $type->match( $c, $path );
         }
 
@@ -470,7 +470,7 @@ cannot determine an appropriate URI, this method will return undef.
 sub uri_for_action {
     my ( $self, $action, $captures) = @_;
     $captures ||= [];
-    foreach my $dispatch_type ( @{ $self->_dispatch_types } ) {
+    foreach my $dispatch_type ( @{ $self->dispatch_types } ) {
         my $uri = $dispatch_type->uri_for_action( $action, $captures );
         return( $uri eq '' ? '/' : $uri )
             if defined($uri);
@@ -489,7 +489,7 @@ single action.
 sub expand_action {
     my ($self, $action) = @_;
 
-    foreach my $dispatch_type (@{ $self->_dispatch_types }) {
+    foreach my $dispatch_type (@{ $self->dispatch_types }) {
         my $expanded = $dispatch_type->expand_action($action);
         return $expanded if $expanded;
     }
@@ -518,12 +518,12 @@ sub register {
             # FIXME - Some error checking and re-throwing needed here, as
             #         we eat exceptions loading dispatch types.
             eval { Class::MOP::load_class($class) };
-            push( @{ $self->_dispatch_types }, $class->new ) unless $@;
+            push( @{ $self->dispatch_types }, $class->new ) unless $@;
             $registered->{$class} = 1;
         }
     }
 
-    my @dtypes = @{ $self->_dispatch_types };
+    my @dtypes = @{ $self->dispatch_types };
     my @normal_dtypes;
     my @low_precedence_dtypes;
 
@@ -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;
@@ -644,7 +647,7 @@ sub _display_action_tables {
       if $has_private;
 
     # List all public actions
-    $_->list($c) for @{ $self->_dispatch_types };
+    $_->list($c) for @{ $self->dispatch_types };
 }
 
 sub _load_dispatch_types {
@@ -655,11 +658,11 @@ sub _load_dispatch_types {
     for my $type (@types) {
         # first param is undef because we cannot get the appclass
         my $class = Catalyst::Utils::resolve_namespace(undef, 'Catalyst::DispatchType', $type);
-        
+
         eval { Class::MOP::load_class($class) };
         Catalyst::Exception->throw( message => qq/Couldn't load "$class"/ )
           if $@;
-        push @{ $self->_dispatch_types }, $class->new;
+        push @{ $self->dispatch_types }, $class->new;
 
         push @loaded, $class;
     }
@@ -681,7 +684,7 @@ sub dispatch_type {
     # first param is undef because we cannot get the appclass
     $name = Catalyst::Utils::resolve_namespace(undef, 'Catalyst::DispatchType', $name);
 
-    for (@{ $self->_dispatch_types }) {
+    for (@{ $self->dispatch_types }) {
         return $_ if ref($_) eq $name;
     }
     return undef;
@@ -694,16 +697,31 @@ use Moose;
 # Various plugins (e.g. Plugin::Server and Plugin::Authorization::ACL)
 # need the methods here which *should* be private..
 
-# However we can't really take them away until there is a sane API for
-# building actions and configuring / introspecting the dispatcher.
-# In 5.90, we should build that infrastructure, port the plugins which
-# use it, and then take the crap below away.
+# You should be able to use get_actions or get_containers appropriately
+# instead of relying on these methods which expose implementation details
+# of the dispatcher..
+#
+# IRC backlog included below, please come ask if this doesn't work for you.
+#
+# <@t0m> 5.80, the state of. There are things in the dispatcher which have
+#        been deprecated, that we yell at anyone for using, which there isn't
+#        a good alternative for yet..
+# <@mst> er, get_actions/get_containers provides that doesn't it?
+# <@mst> DispatchTypes are loaded on demand anyway
+# <@t0m> I'm thinking of things like _tree which is aliased to 'tree' with
+#        warnings otherwise shit breaks.. We're issuing warnings about the
+#        correct set of things which you shouldn't be calling..
+# <@mst> right
+# <@mst> basically, I don't see there's a need for a replacement for anything
+# <@mst> it was never a good idea to call ->tree
+# <@mst> nothingmuch was the only one who did AFAIK
+# <@mst> and he admitted it was a hack ;)
+
 # See also t/lib/TestApp/Plugin/AddDispatchTypes.pm
 
 # Alias _method_name to method_name, add a before modifier to warn..
 foreach my $public_method_name (qw/
         tree
-        dispatch_types
         registered_dispatch_types
         method_action_class
         action_hash
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..8fa1fca 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};
@@ -82,6 +85,7 @@ sub prepare_connection {
     if ( $ENV{SERVER_PORT} == 443 ) {
         $request->secure(1);
     }
+    binmode(STDOUT); # Ensure we are sending bytes.
 }
 
 =head2 $self->prepare_headers($c)
@@ -111,21 +115,24 @@ sub prepare_path {
     my $scheme = $c->request->secure ? 'https' : 'http';
     my $host      = $ENV{HTTP_HOST}   || $ENV{SERVER_NAME};
     my $port      = $ENV{SERVER_PORT} || 80;
+    my $script_name = $ENV{SCRIPT_NAME};
+    $script_name =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go if $script_name;
+
     my $base_path;
     if ( exists $ENV{REDIRECT_URL} ) {
         $base_path = $ENV{REDIRECT_URL};
         $base_path =~ s/$ENV{PATH_INFO}$//;
     }
     else {
-        $base_path = $ENV{SCRIPT_NAME} || '/';
+        $base_path = $script_name || '/';
     }
 
     # 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,10 +141,27 @@ 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};
+        }
+    }
+
+    # RFC 3875: "Unlike a URI path, the PATH_INFO is not URL-encoded,
+    # and cannot contain path-segment parameters." This means PATH_INFO
+    # is always decoded, and the script can't distinguish / vs %2F.
+    # See https://issues.apache.org/bugzilla/show_bug.cgi?id=35256
+    # Here we try to resurrect the original encoded URI from REQUEST_URI.
+    my $path_info   = $ENV{PATH_INFO};
+    if (my $req_uri = $ENV{REQUEST_URI}) {
+        if (defined $script_name) {
+            $req_uri =~ s/^\Q$script_name\E//;
+        }
+        $req_uri =~ s/\?.*$//;
+        $path_info = $req_uri if $req_uri;
     }
 
     # set the request URI
-    my $path = $base_path . ( $ENV{PATH_INFO} || '' );
+    my $path = $base_path . ( $path_info || '' );
     $path =~ s{^/+}{};
 
     # Using URI directly is way too slow, so we construct the URLs manually
index 125a762..85b360c 100644 (file)
@@ -234,8 +234,13 @@ sub _fix_env
     if ( $env->{SERVER_SOFTWARE} =~ /lighttpd/ ) {
         $env->{PATH_INFO} ||= delete $env->{SCRIPT_NAME};
     }
-    # Fix the environment variables PATH_INFO and SCRIPT_NAME when running under IIS
-    elsif ( $env->{SERVER_SOFTWARE} =~ /IIS\/[67].0/ ) {
+    elsif ( $env->{SERVER_SOFTWARE} =~ /^nginx/ ) {
+        my $script_name = $env->{SCRIPT_NAME};
+        $env->{PATH_INFO} =~ s/^$script_name//g;
+    }
+    # Fix the environment variables PATH_INFO and SCRIPT_NAME when running 
+    # under IIS
+    elsif ( $env->{SERVER_SOFTWARE} =~ /IIS\/[6-9]\.[0-9]/ ) {
         my @script_name = split(m!/!, $env->{PATH_INFO});
         my @path_translated = split(m!/|\\\\?!, $env->{PATH_TRANSLATED});
         my @path_info;
@@ -433,6 +438,76 @@ above modes.  Note the required mod_rewrite rule.
 For more information on using FastCGI under Lighttpd, visit
 L<http://www.lighttpd.net/documentation/fastcgi.html>
 
+=head2 nginx
+
+Catalyst runs under nginx via FastCGI in a similar fashion as the lighttpd
+standalone server as described above.
+
+nginx does not have its own internal FastCGI process manager, so you must run
+the FastCGI service separately.
+
+=head3 Configuration
+
+To configure nginx, you must configure the FastCGI parameters and also the
+socket your FastCGI daemon is listening on.  It can be either a TCP socket
+or a Unix file socket.
+
+The server configuration block should look roughly like:
+
+    server {
+        listen $port;
+
+        location / {
+            fastcgi_param  QUERY_STRING       $query_string;
+            fastcgi_param  REQUEST_METHOD     $request_method;
+            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  REQUEST_URI        $request_uri;
+            fastcgi_param  DOCUMENT_URI       $document_uri;
+            fastcgi_param  DOCUMENT_ROOT      $document_root;
+            fastcgi_param  SERVER_PROTOCOL    $server_protocol;
+
+            fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
+            fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
+
+            fastcgi_param  REMOTE_ADDR        $remote_addr;
+            fastcgi_param  REMOTE_PORT        $remote_port;
+            fastcgi_param  SERVER_ADDR        $server_addr;
+            fastcgi_param  SERVER_PORT        $server_port;
+            fastcgi_param  SERVER_NAME        $server_name;
+        
+            # Adjust the socket for your applications!
+            fastcgi_pass   unix:$docroot/myapp.socket;
+        }
+    }
+
+It is the standard convention of nginx to include the fastcgi_params in a
+separate file (usually something like C</etc/nginx/fastcgi_params>) and
+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.
+
+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;
+
+C<$fastcgi_script_name> would be "/myapp/path/of/the/action".  Catalyst will
+process this accordingly and setup the application base as expected.
+
+This behavior is somewhat different than Apache and Lighttpd, but is still
+functional.
+
+For more information on nginx, visit:
+L<http://nginx.net>
+
 =head2 Microsoft IIS
 
 It is possible to run Catalyst under IIS with FastCGI, but only on IIS 6.0
index d58e508..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;
 
@@ -158,11 +154,16 @@ around write => sub {
 
     # Prepend the headers if they have not yet been sent
     if ( $self->_has_header_buf ) {
-        $buffer = $self->_clear_header_buf . $buffer;
+        $self->_warn_on_write_error(
+            $self->$orig($c, $self->_clear_header_buf)
+        );
     }
 
-    my $ret = $self->$orig($c, $buffer);
+    $self->_warn_on_write_error($self->$orig($c, $buffer));
+};
 
+sub _warn_on_write_error {
+    my ($self, $ret) = @_;
     if ( !defined $ret ) {
         $self->_write_error($!);
         DEBUG && warn "write: Failed to write response ($!)\n";
@@ -170,9 +171,8 @@ around write => sub {
     else {
         DEBUG && warn "write: Wrote response ($ret bytes)\n";
     }
-
     return $ret;
-};
+}
 
 =head2 run
 
@@ -364,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         || '',
diff --git a/lib/Catalyst/Engine/HTTP/Restarter.pm b/lib/Catalyst/Engine/HTTP/Restarter.pm
deleted file mode 100644 (file)
index dfb414c..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-package Catalyst::Engine::HTTP::Restarter;
-use Moose;
-use Moose::Util qw/find_meta/;
-use namespace::clean -except => 'meta';
-
-extends 'Catalyst::Engine::HTTP';
-
-use Catalyst::Engine::HTTP::Restarter::Watcher;
-
-around run => sub {
-    my $orig = shift;
-    my ( $self, $class, $port, $host, $options ) = @_;
-
-    $options ||= {};
-
-    # Setup restarter
-    unless ( my $restarter = fork ) {
-
-        # Prepare
-        close STDIN;
-        close STDOUT;
-
-        # Avoid "Setting config after setup" error restarting MyApp.pm
-        $class->setup_finished(0);
-        # Best effort if we can't trap compiles..
-        $self->_make_components_mutable($class)
-            if !Catalyst::Engine::HTTP::Restarter::Watcher::DETECT_PACKAGE_COMPILATION;
-
-        my $watcher = Catalyst::Engine::HTTP::Restarter::Watcher->new(
-            directory => (
-                $options->{restart_directory} ||
-                File::Spec->catdir( $FindBin::Bin, '..' )
-            ),
-            follow_symlinks => $options->{follow_symlinks},
-            regex     => $options->{restart_regex},
-            delay     => $options->{restart_delay},
-        );
-
-        $host ||= '127.0.0.1';
-        while (1) {
-
-            # poll for changed files
-            my @changed_files = $watcher->watch();
-
-            # check if our parent process has died
-            exit if $^O ne 'MSWin32' and getppid == 1;
-
-            # Restart if any files have changed
-            if (@changed_files) {
-                my $files = join ', ', @changed_files;
-                print STDERR qq/File(s) "$files" modified, restarting\n\n/;
-
-                require IO::Socket::INET;
-                require HTTP::Headers;
-                require HTTP::Request;
-
-                my $client = IO::Socket::INET->new(
-                    PeerAddr => $host,
-                    PeerPort => $port
-                  )
-                  or die "Can't create client socket (is server running?): ",
-                  $!;
-
-                # build the Kill request
-                my $req =
-                  HTTP::Request->new( 'RESTART', '/',
-                    HTTP::Headers->new( 'Connection' => 'close' ) );
-                $req->protocol('HTTP/1.0');
-
-                $client->send( $req->as_string )
-                  or die "Can't send restart instruction: ", $!;
-                $client->close();
-                exit;
-            }
-        }
-    }
-
-    return $self->$orig( $class, $port, $host, $options );
-};
-
-# Naive way of trying to avoid Moose blowing up when you re-require components
-# which have been made immutable.
-sub _make_components_mutable {
-    my ($self, $class) = @_;
-
-    my @metas = grep { defined($_) }
-                map { find_meta($_) }
-                ($class, map { blessed($_) }
-                values %{ $class->components });
-
-    foreach my $meta (@metas) {
-        # Paranoia unneeded, all component metaclasses should have immutable
-        $meta->make_mutable if $meta->is_immutable;
-    }
-}
-
-1;
-__END__
-
-=head1 NAME
-
-Catalyst::Engine::HTTP::Restarter - Catalyst Auto-Restarting HTTP Engine
-
-=head1 SYNOPSIS
-
-    script/myapp_server.pl -restart
-
-=head1 DESCRIPTION
-
-The Restarter engine will monitor files in your application for changes
-and restart the server when any changes are detected.
-
-=head1 METHODS
-
-=head2 run
-
-=head1 SEE ALSO
-
-L<Catalyst>, L<Catalyst::Engine::HTTP>, L<Catalyst::Engine::CGI>,
-L<Catalyst::Engine>.
-
-=head1 AUTHORS
-
-Catalyst Contributors, see Catalyst.pm
-
-=head1 THANKS
-
-Many parts are ripped out of C<HTTP::Server::Simple> by Jesse Vincent.
-
-=head1 COPYRIGHT
-
-This library is free software. You can redistribute it and/or modify it under
-the same terms as Perl itself.
-
-=cut
diff --git a/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm b/lib/Catalyst/Engine/HTTP/Restarter/Watcher.pm
deleted file mode 100644 (file)
index 8890646..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-package Catalyst::Engine::HTTP::Restarter::Watcher;
-
-use Moose;
-with 'MooseX::Emulate::Class::Accessor::Fast';
-
-use File::Find;
-use File::Modified;
-use File::Spec;
-use Time::HiRes qw/sleep/;
-use Moose::Util qw/find_meta/;
-use namespace::clean -except => 'meta';
-
-BEGIN {
-    # If we can detect stash changes, then we do magic
-    # to make their metaclass mutable (if they have one)
-    # so that restarting works as expected.
-    eval { require B::Hooks::OP::Check::StashChange; };
-    *DETECT_PACKAGE_COMPILATION = $@
-        ? sub () { 0 }
-        : sub () { 1 }
-}
-
-has delay => (is => 'rw');
-has regex => (is => 'rw');
-has modified => (is => 'rw', builder => '_build_modified', lazy => 1);
-has directory => (is => 'rw');
-has watch_list => (is => 'rw', builder => '_build_watch_list', lazy => 1);
-has follow_symlinks => (is => 'rw');
-
-sub _build_watch_list {
-    my ($self) = @_;
-    return $self->_index_directory;
-}
-
-sub _build_modified {
-    my ($self) = @_;
-    return File::Modified->new(
-        method => 'mtime',
-        files  => [ keys %{ $self->watch_list } ],
-    );
-}
-
-sub watch {
-    my $self = shift;
-
-    my @changes;
-    my @changed_files;
-
-    my $delay = ( defined $self->delay ) ? $self->delay : 1;
-
-    sleep $delay if $delay > 0;
-
-    eval { @changes = $self->modified->changed };
-    if ($@) {
-
-        # File::Modified will die if a file is deleted.
-        my ($deleted_file) = $@ =~ /stat '(.+)'/;
-        push @changed_files, $deleted_file || 'unknown file';
-    }
-
-    if (@changes) {
-
-        # update all mtime information
-        $self->modified->update;
-
-        # check if any files were changed
-        @changed_files = grep { -f $_ } @changes;
-
-        # Check if only directories were changed.  This means
-        # a new file was created.
-        unless (@changed_files) {
-
-            # re-index to find new files
-            my $new_watch = $self->_index_directory;
-
-            # look through the new list for new files
-            my $old_watch = $self->watch_list;
-            @changed_files = grep { !defined $old_watch->{$_} }
-              keys %{$new_watch};
-
-            return unless @changed_files;
-        }
-
-        # Test modified pm's
-        for my $file (@changed_files) {
-            next unless $file =~ /\.pm$/;
-            if ( my $error = $self->_test($file) ) {
-                print STDERR qq/File "$file" modified, not restarting\n\n/;
-                print STDERR '*' x 80, "\n";
-                print STDERR $error;
-                print STDERR '*' x 80, "\n";
-                return;
-            }
-        }
-    }
-
-    return @changed_files;
-}
-
-sub _index_directory {
-    my $self = shift;
-
-    my $dir   = $self->directory;
-    die "No directory specified" if !$dir or ref($dir) && !@{$dir};
-
-    my $regex = $self->regex     || '\.pm$';
-    my %list;
-
-    finddepth(
-        {
-            wanted => sub {
-                my $file = File::Spec->rel2abs($File::Find::name);
-                return unless $file =~ /$regex/;
-                return unless -f $file;
-                $file =~ s{/script/..}{};
-                $list{$file} = 1;
-
-                # also watch the directory for changes
-                my $cur_dir = File::Spec->rel2abs($File::Find::dir);
-                $cur_dir =~ s{/script/..}{};
-                $list{$cur_dir} = 1;
-            },
-            follow_fast => $self->follow_symlinks ? 1 : 0,
-            no_chdir => 1
-        },
-        ref $dir eq 'ARRAY' ? @{$dir} : $dir
-    );
-    return \%list;
-}
-
-sub _test {
-    my ( $self, $file ) = @_;
-
-    my $id;
-    if (DETECT_PACKAGE_COMPILATION) {
-        $id = B::Hooks::OP::Check::StashChange::register(sub {
-            my ($new, $old) = @_;
-            my $meta = find_meta($new);
-            if ($meta) { # A little paranoia here - Moose::Meta::Role has neither of these methods.
-                my $is_immutable = $meta->can('is_immutable');
-                my $make_mutable = $meta->can('make_mutable');
-                $meta->$make_mutable() if $is_immutable && $make_mutable && $meta->$is_immutable();
-                eval { # Do not explode the watcher process if this fails.
-                    my $superclasses = $meta->can('superclasses');
-                    $meta->$superclasses('Moose::Object') if $superclasses;
-                };
-            }
-        });
-    }
-
-    local $Catalyst::__AM_RESTARTING = 1; # Hack to avoid C3 fail
-    delete $INC{$file}; # Remove from %INC so it will reload
-    local $SIG{__WARN__} = sub { };
-
-    open my $olderr, '>&STDERR';
-    open STDERR, '>', File::Spec->devnull;
-    eval "require '$file'";
-    open STDERR, '>&', $olderr;
-
-    B::Hooks::OP::Check::StashChange::unregister($id) if $id;
-
-    return ($@) ? $@ : 0;
-}
-
-1;
-__END__
-
-=head1 NAME
-
-Catalyst::Engine::HTTP::Restarter::Watcher - Watch for changed application
-files
-
-=head1 SYNOPSIS
-
-    my $watcher = Catalyst::Engine::HTTP::Restarter::Watcher->new(
-        directory => '/path/to/MyApp',
-        regex     => '\.yml$|\.yaml$|\.conf|\.pm$',
-        delay     => 1,
-    );
-
-    while (1) {
-        my @changed_files = $watcher->watch();
-    }
-
-=head1 DESCRIPTION
-
-This class monitors a directory of files for changes made to any file
-matching a regular expression.  It correctly handles new files added to the
-application as well as files that are deleted.
-
-=head1 METHODS
-
-=head2 new ( directory => $path [, regex => $regex, delay => $delay ] )
-
-Creates a new Watcher object.
-
-=head2 watch
-
-Returns a list of files that have been added, deleted, or changed since the
-last time watch was called.
-
-=head2 DETECT_PACKAGE_COMPILATION
-
-Returns true if L<B::Hooks::OP::Check::StashChange> is installed and
-can be used to detect when files are compiled. This is used internally
-to make the L<Moose> metaclass of any class being reloaded immutable.
-
-If L<B::Hooks::OP::Check::StashChange> is not installed, then the
-restarter makes all application components immutable. This covers the
-simple case, but is less useful if you're using Moose in components
-outside Catalyst's namespaces, but inside your application directory.
-
-=head1 SEE ALSO
-
-L<Catalyst>, L<Catalyst::Engine::HTTP::Restarter>, L<File::Modified>
-
-=head1 AUTHORS
-
-Catalyst Contributors, see Catalyst.pm
-
-=head1 THANKS
-
-Many parts are ripped out of C<HTTP::Server::Simple> by Jesse Vincent.
-
-=head1 COPYRIGHT
-
-This library is free software. You can redistribute it and/or modify it under
-the same terms as Perl itself.
-
-=cut
index c8d5547..7506483 100644 (file)
@@ -2,12 +2,6 @@ package Catalyst::Exception;
 
 # XXX: See bottom of file for Exception implementation
 
-package Catalyst::Exception::Base;
-
-use Moose;
-use Carp;
-use namespace::clean -except => 'meta';
-
 =head1 NAME
 
 Catalyst::Exception - Catalyst Exception Class
@@ -32,48 +26,6 @@ This is the Catalyst Exception class.
 
 Throws a fatal exception.
 
-=cut
-
-has message => (
-    is      => 'ro',
-    isa     => 'Str',
-    default => sub { $! || '' },
-);
-
-use overload
-    q{""}    => \&as_string,
-    fallback => 1;
-
-sub as_string {
-    my ($self) = @_;
-    return $self->message;
-}
-
-around BUILDARGS => sub {
-    my ($next, $class, @args) = @_;
-    if (@args == 1 && !ref $args[0]) {
-        @args = (message => $args[0]);
-    }
-
-    my $args = $class->$next(@args);
-    $args->{message} ||= $args->{error}
-        if exists $args->{error};
-
-    return $args;
-};
-
-sub throw {
-    my $class = shift;
-    my $error = $class->new(@_);
-    local $Carp::CarpLevel = 1;
-    croak $error;
-}
-
-sub rethrow {
-    my ($self) = @_;
-    croak $self;
-}
-
 =head2 meta
 
 Provided by Moose
@@ -89,19 +41,30 @@ it under the same terms as Perl itself.
 
 =cut
 
-Catalyst::Exception::Base->meta->make_immutable;
-
-package Catalyst::Exception;
+{
+    package Catalyst::Exception::Base;
 
-use Moose;
-use namespace::clean -except => 'meta';
+    use Moose;
+    use namespace::clean -except => 'meta';
 
-use vars qw[$CATALYST_EXCEPTION_CLASS];
+    with 'Catalyst::Exception::Basic';
 
-BEGIN {
-    extends($CATALYST_EXCEPTION_CLASS || 'Catalyst::Exception::Base');
+    __PACKAGE__->meta->make_immutable;
 }
 
-__PACKAGE__->meta->make_immutable;
+{
+    package Catalyst::Exception;
+
+    use Moose;
+    use namespace::clean -except => 'meta';
+
+    use vars qw[$CATALYST_EXCEPTION_CLASS];
+
+    BEGIN {
+        extends($CATALYST_EXCEPTION_CLASS || 'Catalyst::Exception::Base');
+    }
+
+    __PACKAGE__->meta->make_immutable;
+}
 
 1;
diff --git a/lib/Catalyst/Exception/Basic.pm b/lib/Catalyst/Exception/Basic.pm
new file mode 100644 (file)
index 0000000..713bb5f
--- /dev/null
@@ -0,0 +1,107 @@
+package Catalyst::Exception::Basic;
+
+use MooseX::Role::WithOverloading;
+use Carp;
+use namespace::clean -except => 'meta';
+
+with 'Catalyst::Exception::Interface';
+
+has message => (
+    is      => 'ro',
+    isa     => 'Str',
+    default => sub { $! || '' },
+);
+
+sub as_string {
+    my ($self) = @_;
+    return $self->message;
+}
+
+around BUILDARGS => sub {
+    my ($next, $class, @args) = @_;
+    if (@args == 1 && !ref $args[0]) {
+        @args = (message => $args[0]);
+    }
+
+    my $args = $class->$next(@args);
+    $args->{message} ||= $args->{error}
+        if exists $args->{error};
+
+    return $args;
+};
+
+sub throw {
+    my $class = shift;
+    my $error = $class->new(@_);
+    local $Carp::CarpLevel = 1;
+    croak $error;
+}
+
+sub rethrow {
+    my ($self) = @_;
+    croak $self;
+}
+
+1;
+
+=head1 NAME
+
+Catalyst::Exception::Basic - Basic Catalyst Exception Role
+
+=head1 SYNOPSIS
+
+   package My::Exception;
+   use Moose;
+   use namespace::clean -except => 'meta';
+
+   with 'Catalyst::Exception::Basic';
+
+   # Elsewhere..
+   My::Exception->throw( qq/Fatal exception/ );
+
+See also L<Catalyst> and L<Catalyst::Exception>.
+
+=head1 DESCRIPTION
+
+This is the basic Catalyst Exception role which implements all of
+L<Catalyst::Exception::Interface>.
+
+=head1 ATTRIBUTES
+
+=head2 message
+
+Holds the exception message.
+
+=head1 METHODS
+
+=head2 as_string
+
+Stringifies the exception's message attribute.
+Called when the object is stringified by overloading.
+
+=head2 throw( $message )
+
+=head2 throw( message => $message )
+
+=head2 throw( error => $error )
+
+Throws a fatal exception.
+
+=head2 rethrow( $exception )
+
+Rethrows a caught exception.
+
+=head2 meta
+
+Provided by Moose
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
index 5f98119..88f42c1 100644 (file)
@@ -3,7 +3,7 @@ package Catalyst::Exception::Detach;
 use Moose;
 use namespace::clean -except => 'meta';
 
-extends 'Catalyst::Exception';
+with 'Catalyst::Exception::Basic';
 
 has '+message' => (
     default => "catalyst_detach\n",
@@ -19,4 +19,34 @@ __END__
 
 Catalyst::Exception::Detach - Exception for redispatching using $ctx->detach()
 
+=head1 DESCRIPTION
+
+This is the class for the Catalyst Exception which is thrown then you call
+C<< $c->detach() >>.
+
+This class is not intended to be used directly by users.
+
+=head2 meta
+
+Provided by Moose
+
+=head1 SEE ALSO
+
+=over 4
+
+=item L<Catalyst>
+
+=item L<Catalyst::Exception>
+
+=back
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
 =cut
index 6be9efe..f7d7362 100644 (file)
@@ -3,7 +3,7 @@ package Catalyst::Exception::Go;
 use Moose;
 use namespace::clean -except => 'meta';
 
-extends 'Catalyst::Exception';
+with 'Catalyst::Exception::Basic';
 
 has '+message' => (
     default => "catalyst_go\n",
@@ -19,4 +19,34 @@ __END__
 
 Catalyst::Exception::Go - Exception for redispatching using $ctx->go()
 
+=head1 DESCRIPTION
+
+This is the class for the Catalyst Exception which is thrown then you call
+C<< $c->go() >>.
+
+This class is not intended to be used directly by users.
+
+=head2 meta
+
+Provided by Moose
+
+=head1 SEE ALSO
+
+=over 4
+
+=item L<Catalyst>
+
+=item L<Catalyst::Exception>
+
+=back
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
 =cut
diff --git a/lib/Catalyst/Exception/Interface.pm b/lib/Catalyst/Exception/Interface.pm
new file mode 100644 (file)
index 0000000..371bfa3
--- /dev/null
@@ -0,0 +1,77 @@
+package Catalyst::Exception::Interface;
+
+use MooseX::Role::WithOverloading;
+use namespace::clean -except => 'meta';
+
+use overload
+    q{""}    => sub { $_[0]->as_string },
+    fallback => 1;
+
+requires qw/as_string throw rethrow/;
+
+1;
+
+__END__
+
+=head1 NAME
+
+Catalyst::Exception::Interface - Role defining the interface for Catalyst exceptions
+
+=head1 SYNOPSIS
+
+   package My::Catalyst::Like::Exception;
+   use Moose;
+   use namespace::clean -except => 'meta';
+
+   with 'Catalyst::Exception::Interface';
+
+   # This comprises the required interface.
+   sub as_string { 'the exception text for stringification' }
+   sub die { shift; die @_ }
+   sub die { shift; die @_ }
+
+=head1 DESCRIPTION
+
+This is a role for the required interface for Catalyst exceptions.
+
+It ensures that all exceptions follow the expected interface,
+and adds overloading for stringification when composed onto a
+class.
+
+Note that if you compose this role onto another role, that role
+must use L<MooseX::Role::WithOverloading>.
+
+=head1 REQUIRED METHODS
+
+=head2 as_string
+
+=head2 throw
+
+=head2 rethrow
+
+=head1 METHODS
+
+=head2 meta
+
+Provided by Moose
+
+=head1 SEE ALSO
+
+=over 4
+
+=item L<Catalyst>
+
+=item L<Catalyst::Exception>
+
+=back
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
index e872e5e..9c29d1d 100644 (file)
@@ -8,11 +8,6 @@ in the the catalyst trunk, currently at
 
 Make sure you get it from there to ensure you have the latest version.
 
-=head2 5.80000 1st Quarter 2009
-
-Next major planned release, ports Catalyst to Moose, and does some refactoring
-to help app/ctx.
-
 =head2 5.81000 
 
 =over
index b16e59a..4b7de6d 100644 (file)
@@ -110,7 +110,7 @@ has _body => (
 sub body {
   my $self = shift;
   $self->_context->prepare_body();
-  $self->_body(@_) if scalar @_;
+  croak 'body is a reader' if scalar @_;
   return blessed $self->_body ? $self->_body->body : $self->_body;
 }
 
@@ -210,7 +210,7 @@ Returns a reference to an array containing the arguments.
 
 For example, if your action was
 
-    package MyApp::C::Foo;
+    package MyApp::Controller::Foo;
 
     sub moose : Local {
         ...
@@ -223,7 +223,7 @@ Arguments get automatically URI-unescaped for you.
 
 =head2 $req->args
 
-Shortcut for arguments.
+Shortcut for L</arguments>.
 
 =head2 $req->base
 
@@ -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
@@ -473,7 +474,7 @@ Reads a chunk of data from the request body. This method is intended to be
 used in a while loop, reading $maxlength bytes on every call. $maxlength
 defaults to the size of the request if not specified.
 
-You have to set MyApp->config->{parse_on_demand} to use this directly.
+You have to set MyApp->config(parse_on_demand => 1) to use this directly.
 
 =head2 $req->referer
 
@@ -569,7 +570,7 @@ L<Catalyst::Request::Upload> objects.
 
 =head2 $req->uri
 
-Returns a URI object for the current request. Stringifies to the URI text.
+Returns a L<URI> object for the current request. Stringifies to the URI text.
 
 =head2 $req->mangle_params( { key => 'value' }, $appendmode);
 
@@ -649,7 +650,7 @@ You may also pass an optional second parameter that puts C<uri_with> into
 append mode:
 
   $req->uri_with( { key => 'value' }, { mode => 'append' } );
-  
+
 See C<mangle_params> for an explanation of this behavior.
 
 =cut
@@ -675,7 +676,10 @@ sub uri_with {
 =head2 $req->user
 
 Returns the currently logged in user. B<Highly deprecated>, do not call,
-this will be removed in version 5.81.
+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
 
index 595decb..f268aef 100644 (file)
@@ -65,7 +65,7 @@ will turn the Catalyst::Response into a HTTP Response and return it to the clien
 
 =head1 METHODS
 
-=head2 $res->body(<$text|$fh|$iohandle_object)
+=head2 $res->body( $text | $fh | $iohandle_object )
 
     $c->response->body('Catalyst rocks!');
 
@@ -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:
 
@@ -150,7 +150,7 @@ C<302>.
 
 This is a convenience method that sets the Location header to the
 redirect destination, and then sets the response status.  You will
-want to C< return; > or C< $c->detach() > to interrupt the normal
+want to C< return > or C<< $c->detach() >> to interrupt the normal
 processing flow if you want the redirect to occur straight away.
 
 =cut
index 271d7a5..d3c5e5d 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.80014_02';
 
 $VERSION = eval $VERSION;
 
diff --git a/lib/Catalyst/Script/CGI.pm b/lib/Catalyst/Script/CGI.pm
new file mode 100644 (file)
index 0000000..e80a5f7
--- /dev/null
@@ -0,0 +1,34 @@
+package Catalyst::Script::CGI;
+use Moose;
+BEGIN { $ENV{CATALYST_ENGINE} ||= 'CGI' }
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+__PACKAGE__->meta->make_immutable;
+
+=head1 NAME
+
+Catalyst::Script::CGI - The CGI Catalyst Script
+
+=head1 SYNOPSIS
+
+  myapp_cgi.pl [options]
+
+  Options:
+  -h     --help           display this help and exits
+
+=head1 DESCRIPTION
+
+This is a script to run the Catalyst engine specialized for the CGI environment.
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=cut
diff --git a/lib/Catalyst/Script/Create.pm b/lib/Catalyst/Script/Create.pm
new file mode 100644 (file)
index 0000000..7d318fe
--- /dev/null
@@ -0,0 +1,103 @@
+package Catalyst::Script::Create;
+use Moose;
+use MooseX::Types::Moose qw/Bool Str/;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+has force => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'nonew',
+    isa           => Bool,
+    is            => 'ro',
+    documentation => 'Force new scripts',
+);
+
+has debug => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'd',
+    isa           => Bool,
+    is            => 'ro',
+    documentation => 'Force debug mode',
+);
+
+has mechanize => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'mech',
+    isa           => Bool,
+    is            => 'ro',
+    documentation => 'use WWW::Mechanize',
+);
+
+has helper_class => (
+    isa     => Str,
+    is      => 'ro',
+    builder => '_build_helper_class',
+);
+
+sub _build_helper_class { 'Catalyst::Helper' }
+
+sub run {
+    my ($self) = @_;
+
+    $self->_exit_with_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 );
+
+}
+
+__PACKAGE__->meta->make_immutable;
+
+=head1 NAME
+
+Catalyst::Script::Create - Create a new Catalyst Component
+
+=head1 SYNOPSIS
+
+ myapp_create.pl [options] model|view|controller name [helper] [options]
+
+ Options:
+   --force        don't create a .new file where a file to be created exists
+   --mechanize    use Test::WWW::Mechanize::Catalyst for tests if available
+   --help         display this help and exits
+
+ Examples:
+   myapp_create.pl controller My::Controller
+   myapp_create.pl controller My::Controller BindLex
+   myapp_create.pl -mechanize controller My::Controller
+   myapp_create.pl view My::View
+   myapp_create.pl view MyView TT
+   myapp_create.pl view TT TT
+   myapp_create.pl model My::Model
+   myapp_create.pl model SomeDB DBIC::Schema MyApp::Schema create=dynamic\
+   dbi:SQLite:/tmp/my.db
+   myapp_create.pl model AnotherDB DBIC::Schema MyApp::Schema create=static\
+   dbi:Pg:dbname=foo root 4321
+
+ See also:
+   perldoc Catalyst::Manual
+   perldoc Catalyst::Manual::Intro
+
+=head1 DESCRIPTION
+
+Create a new Catalyst Component.
+
+Existing component files are not overwritten.  If any of the component files
+to be created already exist the file will be written with a '.new' suffix.
+This behavior can be suppressed with the C<--force> option.
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
diff --git a/lib/Catalyst/Script/FastCGI.pm b/lib/Catalyst/Script/FastCGI.pm
new file mode 100644 (file)
index 0000000..977bcd6
--- /dev/null
@@ -0,0 +1,121 @@
+package Catalyst::Script::FastCGI;
+
+BEGIN { $ENV{CATALYST_ENGINE} ||= 'FastCGI' }
+use Moose;
+use MooseX::Types::Moose qw/Str Bool Int/;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+has listen => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'l',
+    isa           => Str,
+    is            => 'ro',
+    documentation => 'Specify a listening port/socket',
+);
+
+has pidfile => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'pid',
+    isa           => Str,
+    is            => 'ro',
+    documentation => 'Specify a pidfile',
+);
+
+has daemon => (
+    traits        => [qw(Getopt)],
+    isa           => Bool,
+    is            => 'ro',
+    cmd_aliases   => 'd',
+    documentation => 'Daemonize (go into the background)',
+);
+
+has manager => (
+    traits        => [qw(Getopt)],
+    isa           => Str,
+    is            => 'ro',
+    cmd_aliases   => 'M',
+    documentation => 'Use a different FastCGI process manager class',
+);
+
+has keeperr => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'e',
+    isa           => Bool,
+    is            => 'ro',
+    documentation => 'Log STDERR',
+);
+
+has nproc => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'n',
+    isa           => Int,
+    is            => 'ro',
+    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 (
+        $self->listen,
+        {
+            nproc   => $self->nproc,
+            pidfile => $self->pidfile,
+            manager => $self->manager,
+            detach  => $self->detach,
+            keep_stderr => $self->keeperr,
+        }
+    );
+}
+
+__PACKAGE__->meta->make_immutable;
+
+=head1 NAME
+
+Catalyst::Script::FastCGI - The FastCGI Catalyst Script
+
+=head1 SYNOPSIS
+
+  myapp_fastcgi.pl [options]
+
+ Options:
+   -? --help      display this help and exits
+   -l --listen    Socket path to listen on
+                  (defaults to standard input)
+                  can be HOST:PORT, :PORT or a
+                  filesystem path
+   -n --nproc     specify number of processes to keep
+                  to serve requests (defaults to 1,
+                  requires -listen)
+   -p --pidfile   specify filename for pid file
+                  (requires -listen)
+   -d --daemon    daemonize (requires -listen)
+   -M --manager   specify alternate process manager
+                  (FCGI::ProcManager sub-class)
+                  or empty string to disable
+   -e --keeperr   send error messages to STDOUT, not
+                  to the webserver
+
+=head1 DESCRIPTION
+
+Run a Catalyst application as fastcgi.
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=cut
diff --git a/lib/Catalyst/Script/Server.pm b/lib/Catalyst/Script/Server.pm
new file mode 100644 (file)
index 0000000..77b9d9b
--- /dev/null
@@ -0,0 +1,252 @@
+package Catalyst::Script::Server;
+
+BEGIN {
+    $ENV{CATALYST_ENGINE} ||= 'HTTP';
+    require Catalyst::Engine::HTTP;
+}
+
+use Moose;
+use MooseX::Types::Common::Numeric qw/PositiveInt/;
+use MooseX::Types::Moose qw/ArrayRef Str Bool Int RegexpRef/;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+__PACKAGE__->meta->get_attribute('help')->cmd_aliases('?');
+
+has debug => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'd',
+    isa           => Bool,
+    is            => 'ro',
+    documentation => q{Force debug mode},
+);
+
+has host => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'h',
+    isa           => Str,
+    is            => 'ro',
+    default       => 'localhost',
+    documentation => 'Specify an IP on this host for the server to bind to',
+);
+
+has fork => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'f',
+    isa           => Bool,
+    is            => 'ro',
+    default       => 0,
+    documentation => 'Fork the server to be able to serve multiple requests at once',
+);
+
+has port => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'p',
+    isa           => PositiveInt,
+    is            => 'ro',
+    default       => 3000,
+    documentation => 'Specify a different listening port (to the default port 3000)',
+);
+
+has pidfile => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'pid',
+    isa           => Str,
+    is            => 'ro',
+    documentation => 'Specify a pidfile',
+);
+
+has keepalive => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'k',
+    isa           => Bool,
+    is            => 'ro',
+    default       => 0,
+    documentation => 'Support keepalive',
+);
+
+has background => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'bg',
+    isa           => Bool,
+    is            => 'ro',
+    default       => 0,
+    documentation => 'Run in the background',
+);
+
+has restart => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'r',
+    isa           => Bool,
+    is            => 'ro',
+    default       => 0,
+    documentation => 'use Catalyst::Restarter to detect code changes and restart the application',
+);
+
+has restart_directory => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'rdir',
+    isa           => ArrayRef[Str],
+    is            => 'ro',
+    documentation => 'Restarter directory to watch',
+    predicate     => '_has_restart_directory',
+);
+
+has restart_delay => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'rd',
+    isa           => Int,
+    is            => 'ro',
+    documentation => 'Set a restart delay',
+    predicate     => '_has_restart_delay',
+);
+
+{
+    use Moose::Util::TypeConstraints;
+
+    my $tc = subtype as RegexpRef;
+    coerce $tc, from Str, via { qr/$_/ };
+
+    MooseX::Getopt::OptionTypeMap->add_option_type_to_map($tc => '=s');
+
+    has restart_regex => (
+        traits        => [qw(Getopt)],
+        cmd_aliases   => 'rr',
+        isa           => $tc,
+        coerce        => 1,
+        is            => 'ro',
+        documentation => 'Restart regex',
+        predicate     => '_has_restart_regex',
+    );
+}
+
+has follow_symlinks => (
+    traits        => [qw(Getopt)],
+    cmd_aliases   => 'sym',
+    isa           => Bool,
+    is            => 'ro',
+    default       => 0,
+    documentation => 'Follow symbolic links',
+    predicate     => '_has_follow_symlinks',
+);
+
+sub _restarter_args {
+    my $self = shift;
+
+    return (
+        argv => $self->ARGV,
+        start_sub => sub { $self->_run_application },
+        ($self->_has_follow_symlinks   ? (follow_symlinks => $self->follow_symlinks)   : ()),
+        ($self->_has_restart_delay     ? (sleep_interval  => $self->restart_delay)     : ()),
+        ($self->_has_restart_directory ? (directories     => $self->restart_directory) : ()),
+        ($self->_has_restart_regex     ? (filter          => $self->restart_regex)     : ()),
+    );
+}
+
+sub run {
+    my $self = shift;
+
+    local $ENV{CATALYST_DEBUG} = 1
+        if $self->debug;
+
+    if ( $self->restart ) {
+        die "Cannot run in the background and also watch for changed files.\n"
+            if $self->background;
+
+        # If we load this here, then in the case of a restarter, it does not
+        # need to be reloaded for each restart.
+        require Catalyst;
+
+        # If this isn't done, then the Catalyst::Devel tests for the restarter
+        # fail.
+        $| = 1 if $ENV{HARNESS_ACTIVE};
+
+        require Catalyst::Restarter;
+
+        my $subclass = Catalyst::Restarter->pick_subclass;
+
+        my $restarter = $subclass->new(
+            $self->_restarter_args()
+        );
+
+        $restarter->run_and_watch;
+    }
+    else {
+        $self->_run_application;
+    }
+
+
+}
+
+sub _application_args {
+    my ($self) = shift;
+    return (
+        $self->port,
+        $self->host,
+        {
+           map { $_ => $self->$_ } qw/
+                fork
+                keepalive
+                background
+                pidfile
+                keepalive
+                follow_symlinks
+            /,
+        },
+    );
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
+=head1 NAME
+
+Catalyst::Script::Server - Catalyst test server
+
+=head1 SYNOPSIS
+
+ myapp_server.pl [options]
+
+ Options:
+   -d     --debug          force debug mode
+   -f     --fork           handle each request in a new process
+                      (defaults to false)
+          --help           display this help and exits
+   -h     --host           host (defaults to all)
+   -p     --port           port (defaults to 3000)
+   -k     --keepalive      enable keep-alive connections
+   -r     --restart        restart when files get modified
+                       (defaults to false)
+   --rd   --restartdelay  delay between file checks
+                      (ignored if you have Linux::Inotify2 installed)
+   --rr   --restartregex  regex match files that trigger
+                      a restart when modified
+                      (defaults to '\.yml$|\.yaml$|\.conf|\.pm$')
+   --rdir --restartdirectory  the directory to search for
+                      modified files, can be set mulitple times
+                      (defaults to '[SCRIPT_DIR]/..')
+   --sym  --follow_symlinks   follow symlinks in search directories
+                      (defaults to false. this is a no-op on Win32)
+   --bg   --background        run the process in the background
+   --pid  --pidfile           specify filename for pid file
+
+ See also:
+   perldoc Catalyst::Manual
+   perldoc Catalyst::Manual::Intro
+
+=head1 DESCRIPTION
+
+Run a Catalyst test server for this application.
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
diff --git a/lib/Catalyst/Script/Test.pm b/lib/Catalyst/Script/Test.pm
new file mode 100644 (file)
index 0000000..53473a4
--- /dev/null
@@ -0,0 +1,43 @@
+package Catalyst::Script::Test;
+use Moose;
+use Catalyst::Test ();
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run {
+    my $self = shift;
+
+    Catalyst::Test->import($self->application_name);
+
+    print request($self->ARGV->[0])->content  . "\n";
+}
+
+
+__PACKAGE__->meta->make_immutable;
+
+=head1 NAME
+
+Catalyst::Script::Test - Test Catalyst application on the command line
+
+=head1 SYNOPSIS
+
+  myapp_test.pl [options] /path
+
+  Options:
+  -h     --help           display this help and exits
+
+=head1 DESCRIPTION
+
+Script to perform a test hit against your application and display the output.
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=cut
diff --git a/lib/Catalyst/ScriptRole.pm b/lib/Catalyst/ScriptRole.pm
new file mode 100644 (file)
index 0000000..535ed3d
--- /dev/null
@@ -0,0 +1,112 @@
+package Catalyst::ScriptRole;
+use Moose::Role;
+use MooseX::Types::Moose qw/Str Bool/;
+use Pod::Usage;
+use MooseX::Getopt;
+use namespace::autoclean;
+
+with 'MooseX::Getopt' => {
+    excludes => [qw/
+        _getopt_spec_warnings
+        _getopt_spec_exception
+        _getopt_full_usage
+    /],
+};
+
+has application_name => (
+    traits   => ['NoGetopt'],
+    isa      => Str,
+    is       => 'ro',
+    required => 1,
+);
+
+has help => (
+    traits        => ['Getopt'],
+    isa           => Bool,
+    is            => 'ro',
+    documentation => 'Display this help and exit',
+    cmd_aliases   => ['?', 'h'],
+);
+
+sub _getopt_spec_exception {}
+
+sub _getopt_spec_warnings {
+    shift;
+    warn @_;
+}
+
+sub _getopt_full_usage {
+    my $self = shift;
+    pod2usage();
+    exit 0;
+}
+
+before run => sub {
+    my $self = shift;
+    $self->_getopt_full_usage if $self->help;
+};
+
+sub run {
+    my $self = shift;
+    $self->_run_application;
+}
+
+sub _application_args {
+    ()
+}
+
+sub _run_application {
+    my $self = shift;
+    my $app = $self->application_name;
+    Class::MOP::load_class($app);
+    $app->run($self->_application_args);
+}
+
+1;
+
+=head1 NAME
+
+Catalyst::ScriptRole - Common functionality for Catalyst scripts.
+
+=head1 SYNOPSIS
+
+    package MyApp::Script::Foo;
+    use Moose;
+    use namespace::autoclean;
+
+    with 'Catalyst::ScriptRole';
+
+    sub _application_args { ... }
+
+=head1 DESCRIPTION
+
+Role with the common functionality of Catalyst scripts.
+
+=head1 METHODS
+
+=head2 run
+
+The method invoked to run the application.
+
+=head1 ATTRIBUTES
+
+=head2 application_name
+
+The name of the application class, e.g. MyApp
+
+=head1 SEE ALSO
+
+L<Catalyst>
+
+L<MooseX::Getopt>
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
diff --git a/lib/Catalyst/ScriptRunner.pm b/lib/Catalyst/ScriptRunner.pm
new file mode 100644 (file)
index 0000000..247ce30
--- /dev/null
@@ -0,0 +1,56 @@
+package Catalyst::ScriptRunner;
+use Moose;
+use FindBin;
+use lib;
+use File::Spec;
+use namespace::autoclean;
+
+sub run {
+    my ($self, $class, $scriptclass) = @_;
+    my $classtoload = "${class}::Script::$scriptclass";
+
+    lib->import(File::Spec->catdir($FindBin::Bin, '..', 'lib'));
+
+    unless ( eval { Class::MOP::load_class($classtoload) } ) {
+        warn("Could not load $classtoload - falling back to Catalyst::Script::$scriptclass : $@\n")
+            if $@ !~ /Can't locate/;
+        $classtoload = "Catalyst::Script::$scriptclass";
+        Class::MOP::load_class($classtoload);
+    }
+    $classtoload->new_with_options( application_name => $class )->run;
+}
+
+__PACKAGE__->meta->make_immutable;
+
+=head1 NAME
+
+Catalyst::ScriptRunner - The Catalyst Framework script runner
+
+=head1 SYNOPSIS
+
+    # Will run MyApp::Script::Server if it exists, otherwise
+    # will run Catalyst::Script::Server.
+    Catalyst::ScriptRunner->run('MyApp', 'Server');
+
+=head1 DESCRIPTION
+
+This class is responsible for running scripts, either in the application specific namespace
+(e.g. C<MyApp::Script::Server>), or the Catalyst namespace (e.g. C<Catalyst::Script::Server>)
+
+=head1 METHODS
+
+=head2 run ($application_class, $scriptclass)
+
+Called with two parameters, the application classs (e.g. MyApp)
+and the script class, (i.e. one of Server/FastCGI/CGI/Create/Test)
+
+=head1 AUTHORS
+
+Catalyst Contributors, see Catalyst.pm
+
+=head1 COPYRIGHT
+
+This library is free software. You can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=cut
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 3b319ed..8776803 100644 (file)
@@ -156,8 +156,8 @@ L<HTTP::Request::AsCGI> or remotely if you define the CATALYST_SERVER
 environment variable. This module also adds a few Catalyst-specific
 testing methods as displayed in the method section.
 
-The L<get> and L<request> functions take either a URI or an L<HTTP::Request>
-object.
+The L<get|/"$content = get( ... )"> and L<request|/"$res = request( ... );">
+functions take either a URI or an L<HTTP::Request> object.
 
 =head1 INLINE TESTS WILL NO LONGER WORK
 
@@ -187,7 +187,7 @@ Returns the content.
 
 Note that this method doesn't follow redirects, so to test for a
 correctly redirecting page you'll need to use a combination of this
-method and the L<request> method below:
+method and the L<request|/"$res = request( ... );"> method below:
 
     my $res = request('/'); # redirects to /y
     warn $res->header('location');
@@ -208,7 +208,7 @@ header configuration; currently only supports setting 'host' value.
 
 =head2 ($res, $c) = ctx_request( ... );
 
-Works exactly like L<request>, except it also returns the Catalyst context object,
+Works exactly like L<request|/"$res = request( ... );">, except it also returns the Catalyst context object,
 C<$c>. Note that this only works for local requests.
 
 =head2 $res = Catalyst::Test::local_request( $AppClass, $url );
@@ -228,7 +228,9 @@ sub local_request {
 
     $class->handle_request( env => \%ENV );
 
-    return $cgi->restore->response;
+    my $response = $cgi->restore->response;
+    $response->request( $request );
+    return $response;
 }
 
 my $agent;
index 0410bcf..4fd14d8 100644 (file)
@@ -32,7 +32,8 @@ L<Moose> in your applications.
 
 =head2 Controller actions in Moose roles
 
-Declaring actions in Roles is currently unsupported.
+You can use L<MooseX::MethodAttributes::Role> if you want to declare actions
+inside Moose roles.
 
 =head2 Using Moose in Components
 
@@ -304,6 +305,43 @@ COMPONENT method in your @ISA.
 
 =head1 WARNINGS
 
+=head2 Actions in your application class
+
+Having actions in your application class will now emit a warning at application
+startup as this is deprecated. It is highly recommended that these actions are moved
+into a MyApp::Controller::Root (as demonstrated by the scaffold application
+generated by catalyst.pl). 
+
+This warning, also affects tests. You should move actions in your test,
+creating a myTest::Controller::Root, like the following example:
+
+    package MyTest::Controller::Root;
+
+    use strict;
+    use warnings;
+
+    use parent 'Catalyst::Controller';
+
+    __PACKAGE__->config(namespace => '');
+
+    sub action : Local {
+        my ( $self, $c ) = @_;
+        $c->do_something; 
+    }
+
+    1;
+
+=head2 ::[MVC]:: naming scheme
+
+Having packages called MyApp::[MVC]::XX is deprecated and can no longer be generated
+by catalyst.pl
+
+This is still supported, but it is recommended that you rename your application
+components to Model/View/Controller.
+
+A warning will be issued at application startup if the ::[MVC]:: naming scheme is
+in use.
+
 =head2 Catalyst::Base
 
 Any code using L<Catalyst::Base> will now emit a warning; this
@@ -363,7 +401,7 @@ to B<any> of the packages defined within that component.
 Calling the plugin method is deprecated, and calling it at run time is B<highly
 deprecated>.
 
-Instead you are recommended to use L< Catalyst::Model::Adaptor > or similar to
+Instead you are recommended to use L<Catalyst::Model::Adaptor> or similar to
 compose the functionality you need outside of the main application name space.
 
 Calling the plugin method will not be supported past Catalyst 5.81.
index 05248fc..53bf795 100644 (file)
@@ -124,7 +124,7 @@ sub class2prefix {
 Returns a tempdir for a class. If create is true it will try to create the path.
 
     My::App becomes /tmp/my/app
-    My::App::C::Foo::Bar becomes /tmp/my/app/c/foo/bar
+    My::App::Controller::Foo::Bar becomes /tmp/my/app/c/foo/bar
 
 =cut
 
@@ -172,8 +172,9 @@ sub home {
             # pop off /lib and /blib if they're there
             $home = $home->parent while $home =~ /b?lib$/;
 
-            # only return the dir if it has a Makefile.PL or Build.PL
-            if (-f $home->file("Makefile.PL") or -f $home->file("Build.PL")) {
+            # only return the dir if it has a Makefile.PL or Build.PL or dist.ini
+            if (-f $home->file("Makefile.PL") or -f $home->file("Build.PL")
+                or -f $home->file("dist.ini")) {
 
                 # clean up relative path:
                 # MyApp/script/.. -> MyApp
index 287c12e..ef9771c 100755 (executable)
@@ -26,14 +26,12 @@ my $force    = 0;
 my $help     = 0;
 my $makefile = 0;
 my $scripts  = 0;
-my $short    = 0;
 
 GetOptions(
     'help|?'      => \$help,
     'force|nonew' => \$force,
     'makefile'    => \$makefile,
     'scripts'     => \$scripts,
-    'short'       => \$short
 );
 
 pod2usage(1) if ( $help || !$ARGV[0] );
@@ -43,9 +41,10 @@ my $helper = Catalyst::Helper->new(
         '.newfiles' => !$force,
         'makefile'  => $makefile,
         'scripts'   => $scripts,
-        'short'     => $short,
+        name => $ARGV[0],
     }
 );
+# Pass $ARGV[0] for compatibility with old ::Devel
 pod2usage(1) unless $helper->mk_app( $ARGV[0] );
 
 1;
@@ -67,7 +66,6 @@ upgrade the skeleton of your old application.
    -help       display this help and exit
    -makefile   only update Makefile.PL
    -scripts    only update helper scripts
-   -short      use short names, M/V/C instead of Model/View/Controller.
 
  application-name must be a valid Perl module name and can include "::", 
  which will be converted to '-' in the project name.
diff --git a/t/02pod.t b/t/02pod.t
deleted file mode 100644 (file)
index 05aa78a..0000000
--- a/t/02pod.t
+++ /dev/null
@@ -1,7 +0,0 @@
-use Test::More;
-
-eval "use Test::Pod 1.14";
-plan skip_all => 'Test::Pod 1.14 required' if $@;
-plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD} || -e 'inc/.author';
-
-all_pod_files_ok();
diff --git a/t/03podcoverage.t b/t/03podcoverage.t
deleted file mode 100644 (file)
index 61a207b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-use Test::More;
-
-eval "use Pod::Coverage 0.19";
-plan skip_all => 'Pod::Coverage 0.19 required' if $@;
-eval "use Test::Pod::Coverage 1.04";
-plan skip_all => 'Test::Pod::Coverage 1.04 required' if $@;
-plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD} || -e 'inc/.author';
-
-all_pod_coverage_ok(
-  { 
-    also_private => ['BUILD']
-  }
-);
diff --git a/t/04critic.t b/t/04critic.t
deleted file mode 100644 (file)
index 5a4a226..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-use strict;
-use warnings;
-
-use File::Spec;
-use FindBin ();
-use Test::More;
-
-if ( !-e "$FindBin::Bin/../MANIFEST.SKIP" ) {
-    plan skip_all => 'Critic test only for developers.';
-}
-else {
-    eval { require Test::NoTabs };
-    if ( $@ ) {
-        plan tests => 1;
-        fail( 'You must install Test::NoTabs to run 04critic.t' );
-        exit;
-    }
-}
-
-Test::NoTabs->import;
-all_perl_files_ok(qw/lib/);
similarity index 98%
rename from t/c3_mro.t
rename to t/aggregate/c3_mro.t
index d987544..99057c8 100644 (file)
@@ -15,7 +15,7 @@ my @cat_mods;
 
   local @INC = grep {/blib/} @INC;
   @cat_mods = (
-    'Catalyst', 
+    'Catalyst',
     Module::Pluggable::Object->new(search_path => ['Catalyst'])->plugins,
   );
 }
similarity index 93%
rename from t/caf_backcompat.t
rename to t/aggregate/caf_backcompat.t
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
@@ -4,7 +4,7 @@ use strict;
 use warnings;
 
 use FindBin;
-use lib "$FindBin::Bin/lib";
+use lib "$FindBin::Bin/../lib";
 
 our $iters;
 
@@ -22,23 +22,23 @@ else {
         run_tests();
     }
 }
-    
+
 sub run_tests {
     SKIP:
     {
         if ( $ENV{CATALYST_SERVER} ) {
             skip 'Using remote server', 3;
         }
-        
+
         {
             my @expected = qw[
-                TestAppDoubleAutoBug->auto
-                TestAppDoubleAutoBug->default
-                TestAppDoubleAutoBug->end
+                TestAppDoubleAutoBug::Controller::Root->auto
+                TestAppDoubleAutoBug::Controller::Root->default
+                TestAppDoubleAutoBug::Controller::Root->end
             ];
-    
+
             my $expected = join( ", ", @expected );
-    
+
             ok( my $response = request('http://localhost/action/auto/one'), 'auto + local' );
             is( $response->header('X-Catalyst-Executed'),
                 $expected, 'Executed actions' );
similarity index 94%
rename from t/custom_live_path_bug.t
rename to t/aggregate/custom_live_path_bug.t
index 9bbbd55..a6081c4 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use warnings;
 
 use FindBin;
-use lib "$FindBin::Bin/lib";
+use lib "$FindBin::Bin/../lib";
 
 our $iters;
 
@@ -22,14 +22,14 @@ else {
         run_tests();
     }
 }
-    
+
 sub run_tests {
     SKIP:
     {
         if ( $ENV{CATALYST_SERVER} ) {
             skip 'Using remote server', 2;
         }
-        
+
         {
             my $expected = 'This is the foo method.';
             ok( my $response = request('http://localhost/'), 'response ok' );
index bf566dc..bb34e13 100644 (file)
@@ -35,7 +35,7 @@ sub run_tests {
           TestApp::Controller::Action::Auto->begin
           TestApp::Controller::Action::Auto->auto
           TestApp::Controller::Action::Auto->one
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
     
         my $expected = join( ", ", @expected );
@@ -52,7 +52,7 @@ sub run_tests {
           TestApp::Controller::Action::Auto->begin
           TestApp::Controller::Action::Auto->auto
           TestApp::Controller::Action::Auto->default
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
     
         my $expected = join( ", ", @expected );
@@ -70,7 +70,7 @@ sub run_tests {
           TestApp::Controller::Action::Auto->auto
           TestApp::Controller::Action::Auto::Deep->auto
           TestApp::Controller::Action::Auto::Deep->one
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
     
         my $expected = join( ", ", @expected );
@@ -88,7 +88,7 @@ sub run_tests {
           TestApp::Controller::Action::Auto->auto
           TestApp::Controller::Action::Auto::Deep->auto
           TestApp::Controller::Action::Auto::Deep->default
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
     
         my $expected = join( ", ", @expected );
index 49b3163..e5b2e0f 100644 (file)
@@ -30,7 +30,7 @@ sub run_tests {
           TestApp::Controller::Action::Begin->begin
           TestApp::Controller::Action::Begin->default
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
index 615289c..8a6a449 100644 (file)
@@ -10,7 +10,7 @@ our $iters;
 
 BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
 
-use Test::More tests => 148*$iters;
+use Test::More;
 use Catalyst::Test 'TestApp';
 
 if ( $ENV{CAT_BENCHMARK} ) {
@@ -815,7 +815,7 @@ sub run_tests {
         my @expected = qw[
           TestApp::Controller::Action::Chained::Root->rootsub
           TestApp::Controller::Action::Chained::Root->endpointsub
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
@@ -908,6 +908,29 @@ sub run_tests {
         is( $response->content => 'a; anchor.html', 'Content OK' );
     }
 
+    # CaptureArgs(1) PathPart('...') 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->one_arg
+          TestApp::Controller::Action::Chained::CaptureArgs->edit_one_arg
+          TestApp::Controller::Action::Chained::CaptureArgs->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # should dispatch to /base/one_args/edit_one_arg
+        ok( my $response = request('http://localhost/captureargs/one/edit'),
+            'Correct arg order ran' );
+        TODO: {
+        local $TODO = 'Known bug';
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'base; one_arg; edit_one_arg', 'Content OK' );
+        }
+    }
+
     #
     #   Args(0) should win over Args() if we actually have no arguments.
     {
@@ -1018,5 +1041,31 @@ sub run_tests {
             'request with URI-encoded arg' );
         like( $content, qr{foo/bar;\z}, 'args decoded' );
     }
+
+    # Test round tripping, specifically the / character %2F in uri_for:
+    # not being able to feed it back action + captureargs and args into uri for
+    # and result in the original request uri is a major piece of suck ;)
+    foreach my $thing (
+        ['foo', 'bar'],
+        ['foo%2Fbar', 'baz'],
+        ['foo', 'bar%2Fbaz'],
+        ['foo%2Fbar', 'baz%2Fquux'],
+        ['foo%2Fbar', 'baz%2Fquux', { foo => 'bar', 'baz' => 'quux%2Ffrood'}],
+        ['foo%2Fbar', 'baz%2Fquux', { foo => 'bar', 'baz%2Ffnoo' => 'quux%2Ffrood'}],
+    ) {
+        my $path = '/chained/roundtrip_urifor/' .
+            $thing->[0] . '/' . $thing->[1];
+        $path .= '?' . join('&',
+            map { $_ .'='. $thing->[2]->{$_}}
+            sort keys %{$thing->[2]}) if $thing->[2];
+        ok( my $content =
+            get('http://localhost/' . $path),
+            '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' );
+    }
 }
 
+done_testing;
+
index 935a326..51940d4 100644 (file)
@@ -29,7 +29,7 @@ sub run_tests {
           TestApp::Controller::Action::Default->begin
           TestApp::Controller::Action::Default->default
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
@@ -76,7 +76,7 @@ sub run_tests {
         my @expected = qw[
           TestApp::Controller::Action->begin
           TestApp::Controller::Action->default
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
         
         my $expected = join( ", ", @expected );
index 5905596..2f43a53 100644 (file)
@@ -30,7 +30,7 @@ sub run_tests {
           TestApp::Controller::Action::Detach->one
           TestApp::Controller::Action::Detach->two
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
@@ -57,7 +57,7 @@ sub run_tests {
           TestApp::Controller::Action::Detach->path
           TestApp::Controller::Action::Detach->two
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
index 3000398..3d838b8 100644 (file)
@@ -33,7 +33,7 @@ sub run_tests {
           TestApp::Controller::Action::Forward->four
           TestApp::Controller::Action::Forward->five
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
@@ -81,7 +81,7 @@ sub run_tests {
           TestApp::Controller::Action::Forward->four
           TestApp::Controller::Action::Forward->five
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
@@ -156,7 +156,7 @@ sub run_tests {
           TestApp::Controller::Action::Forward->four
           TestApp::Controller::Action::Forward->five
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
@@ -191,7 +191,7 @@ sub run_tests {
           TestApp::Controller::Action::Forward->four
           TestApp::Controller::Action::Forward->five
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
index 9966a94..8554f72 100644 (file)
@@ -43,7 +43,7 @@ sub run_tests {
           TestApp::Controller::Action::Go->four
           TestApp::Controller::Action::Go->five
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         @expected = map { /Action/ ? (_begin($_), $_) : ($_) } @expected;
@@ -74,7 +74,7 @@ sub run_tests {
         my @expected = qw[
           TestApp::Controller::Action::Go->go_die
           TestApp::Controller::Action::Go->args
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         @expected = map { /Action/ ? (_begin($_), $_) : ($_) } @expected;
@@ -165,7 +165,7 @@ sub run_tests {
           TestApp::Controller::Action::Go->four
           TestApp::Controller::Action::Go->five
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         @expected = map { /Action/ ? (_begin($_), $_) : ($_) } @expected;
@@ -200,7 +200,7 @@ sub run_tests {
           TestApp::Controller::Action::Go->four
           TestApp::Controller::Action::Go->five
           TestApp::View::Dump::Request->process
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         @expected = map { /Action/ ? (_begin($_), $_) : ($_) } @expected;
@@ -262,7 +262,7 @@ sub run_tests {
         ok( my $response = request('http://localhost/action/go/go_chained'), 'go to chained + subcontroller endpoint' );
         is( $response->header('X-Catalyst-Executed'),
             $expected, 'Executed actions' );
-        is( $response->content, 'arg1, arg2; captureme', 'Content OK' );
+        is( $response->content, 'captureme; arg1, arg2', 'Content OK' );
     }
 
 }
index 99e9435..7cd24a9 100644 (file)
@@ -27,8 +27,8 @@ sub run_tests {
     # test root index
     {
         my @expected = qw[
-          TestApp->index
-          TestApp->end
+          TestApp::Controller::Root->index
+          TestApp::Controller::Root->end
         ];
     
         my $expected = join( ", ", @expected );
@@ -45,7 +45,7 @@ sub run_tests {
     {
         my @expected = qw[
           TestApp::Controller::Index->index
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
     
         my $expected = join( ", ", @expected );
@@ -66,7 +66,7 @@ sub run_tests {
         my @expected = qw[
           TestApp::Controller::Action::Index->begin
           TestApp::Controller::Action::Index->index
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
     
         my $expected = join( ", ", @expected );
@@ -87,7 +87,7 @@ sub run_tests {
         my @expected = qw[
           TestApp::Controller::Action::Index->begin
           TestApp::Controller::Action::Index->default
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
     
         my $expected = join( ", ", @expected );
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 468496b..b331e7c 100644 (file)
@@ -42,11 +42,11 @@ sub run_tests {
           TestApp::Controller::Action::Visit->four
           TestApp::Controller::Action::Visit->five
           TestApp::View::Dump::Request->process
-          TestApp->end
-          TestApp->end
-          TestApp->end
-          TestApp->end
-          TestApp->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
         ];
 
         @expected = map { /Action/ ? (_begin($_), $_) : ($_) } @expected;
@@ -76,8 +76,8 @@ sub run_tests {
         my @expected = qw[
           TestApp::Controller::Action::Visit->visit_die
           TestApp::Controller::Action::Visit->args
-          TestApp->end
-          TestApp->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
         ];
 
         @expected = map { /Action/ ? (_begin($_), $_) : ($_) } @expected;
@@ -166,12 +166,12 @@ sub run_tests {
           TestApp::Controller::Action::Visit->four
           TestApp::Controller::Action::Visit->five
           TestApp::View::Dump::Request->process
-          TestApp->end
-          TestApp->end
-          TestApp->end
-          TestApp->end
-          TestApp->end
-          TestApp->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
         ];
 
         @expected = map { /Action/ ? (_begin($_), $_) : ($_) } @expected;
@@ -206,12 +206,12 @@ sub run_tests {
           TestApp::Controller::Action::Visit->four
           TestApp::Controller::Action::Visit->five
           TestApp::View::Dump::Request->process
-          TestApp->end
-          TestApp->end
-          TestApp->end
-          TestApp->end
-          TestApp->end
-          TestApp->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
+          TestApp::Controller::Root->end
         ];
 
         @expected = map { /Action/ ? (_begin($_), $_) : ($_) } @expected;
@@ -266,7 +266,7 @@ sub run_tests {
           TestApp::Controller::Action::Chained->foo
           TestApp::Controller::Action::Chained::Foo->spoon
           TestApp::Controller::Action::Chained->end
-          TestApp->end
+          TestApp::Controller::Root->end
         ];
 
         my $expected = join( ", ", @expected );
@@ -276,7 +276,7 @@ sub run_tests {
                 "visit to chained + subcontroller endpoint for $i" );
             is( $response->header('X-Catalyst-Executed'),
                 $expected, "Executed actions for $i" );
-            is( $response->content, "arg1, arg2; becomescapture",
+            is( $response->content, "becomescapture; arg1, arg2",
                 "Content OK for $i" );
         }
     }
diff --git a/t/aggregate/live_component_controller_anon.t b/t/aggregate/live_component_controller_anon.t
new file mode 100644 (file)
index 0000000..d7a9a2c
--- /dev/null
@@ -0,0 +1,24 @@
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 6;
+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 catalyst_component_name');
+    isnt($response->header('X-Component-Instance-Name-Action'),
+        'TestApp::Controller::Anon', 'ref($controller) ne catalyst_component_name');
+    is($response->header('X-Component-Name-Controller'),
+        'TestApp::Controller::Anon', 'Controller can see correct catalyst_component_name');
+    is($response->header('X-Class-In-Action'),
+        '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 c6670da..954291c 100644 (file)
@@ -80,13 +80,13 @@ use HTTP::Request::Common;
 # 5.80 regression, see note in Catalyst::Plugin::Test::Plugin
 {
     my $request = GET(
-        'http://localhost/have_req_body_in_prepare_action',
+        'http://localhost/dump/response',
         'Content-Type' => 'text/plain',
         'Content'      => 'x' x 100_000
     );
 
     ok( my $response = request($request), 'Request' );
     ok( $response->is_success, 'Response Successful 2xx' );
-    like( $response->content, qr/^[1-9]/, 'Has body' );
+    ok( $response->header('X-Have-Request-Body'), 'X-Have-Request-Body set' );
 }
 
index fbc12ba..fca5a05 100644 (file)
@@ -13,7 +13,7 @@ use HTTP::Request::AsCGI;
 
 This test exposes a problem in the handling of PATH_INFO in C::Engine::CGI (and
 other engines) where Catalyst does not un-escape the request correctly.
-If a request is URL-encoded then Catalyst fails to decode the request 
+If a request is URL-encoded then Catalyst fails to decode the request
 and thus will try and match actions using the URL-encoded value.
 
 Can NOT use Catalyst::Test as it uses HTTP::Request::AsCGI which does
@@ -31,11 +31,11 @@ Index: lib/Catalyst/Engine/CGI.pm
 @@ -157,6 +157,8 @@
      my $query = $ENV{QUERY_STRING} ? '?' . $ENV{QUERY_STRING} : '';
      my $uri   = $scheme . '://' . $host . '/' . $path . $query;
+
 +    $uri = URI->new( $uri )->canonical;
 +
      $c->request->uri( bless \$uri, $uri_class );
+
      # set the base URI
 
 =cut
@@ -54,8 +54,7 @@ Index: lib/Catalyst/Engine/CGI.pm
 }
 
 # test that request with URL-escaped code works.
-TODO: {
-    local $TODO = 'Actions should match when path parts are url encoded';
+{
     my $request = Catalyst::Utils::request( 'http://localhost/args/param%73/one/two' );
     my $cgi     = HTTP::Request::AsCGI->new( $request, %ENV )->setup;
 
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' );
+    }
 }
similarity index 95%
rename from t/meta_method_unneeded.t
rename to t/aggregate/meta_method_unneeded.t
index aa43472..f52a9b4 100644 (file)
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 use FindBin qw/$Bin/;
-use lib "$Bin/lib";
+use lib "$Bin/../lib";
 use Test::More tests => 1;
 use Test::Exception;
 use Carp ();
diff --git a/t/aggregate/unit_controller_actions.t b/t/aggregate/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/];
+
diff --git a/t/aggregate/unit_core_action.t b/t/aggregate/unit_core_action.t
new file mode 100644 (file)
index 0000000..ca84422
--- /dev/null
@@ -0,0 +1,54 @@
+use Test::More tests => 6;
+use strict;
+use warnings;
+use Moose::Meta::Class;
+#use Moose::Meta::Attribute;
+use Catalyst::Request;
+
+use_ok('Catalyst::Action');
+
+my $action_1 = Catalyst::Action->new(
+  name => 'foo',
+  code => sub { "DUMMY" },
+  reverse => 'bar/foo',
+  namespace => 'bar',
+  attributes => {
+    Args => [ 1 ],
+    attr2 => [ 2 ],
+  },
+);
+
+my $action_2 = Catalyst::Action->new(
+  name => 'foo',
+  code => sub { "DUMMY" },
+  reverse => 'bar/foo',
+  namespace => 'bar',
+  attributes => {
+    Args => [ 2 ],
+    attr2 => [ 2 ],
+  },
+);
+
+is("${action_1}", $action_1->reverse, 'overload string');
+is($action_1->(), 'DUMMY', 'overload code');
+
+my $anon_meta = Moose::Meta::Class->create_anon_class(
+  attributes => [
+    Moose::Meta::Attribute->new(
+      request => (
+        reader => 'request',
+        required => 1,
+        default => sub { Catalyst::Request->new(arguments => [qw/one two/]) },
+      ),
+    ),
+  ],
+  methods => { req => sub { shift->request(@_) } }
+);
+
+my $mock_c = $anon_meta->new_object();
+$mock_c->request;
+
+ok(!$action_1->match($mock_c), 'bad match fails');
+ok($action_2->match($mock_c), 'good match works');
+
+ok($action_2->compare( $action_1 ), 'compare works');
index 3e75eaa..c0af9d3 100644 (file)
@@ -12,7 +12,7 @@ plan tests => 4;
 
 use_ok('TestApp');
 
-is(TestApp->action_for('global_action')->code, TestApp->can('global_action'),
+is(TestApp->action_for('global_action')->code, TestApp::Controller::Root->can('global_action'),
    'action_for on appclass ok');
 
 is(TestApp->controller('Args')->action_for('args')->code,
similarity index 98%
rename from t/unit_core_classdata.t
rename to t/aggregate/unit_core_classdata.t
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');
+
similarity index 99%
rename from t/unit_core_component.t
rename to t/aggregate/unit_core_component.t
index 53d6567..69ac6c0 100644 (file)
@@ -89,5 +89,5 @@ is_deeply([ MyApp->comp('Foo') ], \@complist, 'Fallthrough return ok');
 
     $c->component('Mode', qw/foo3 bar3/);
     is_deeply($args, [qw/foo3 bar3/], 'args passed to ACCEPT_CONTEXT ok');
-} 
+}
 
similarity index 81%
rename from t/unit_core_component_loading.t
rename to t/aggregate/unit_core_component_loading.t
index c8098c6..2c53144 100644 (file)
@@ -1,7 +1,8 @@
 # 2 initial tests, and 6 per component in the loop below
 # (do not forget to update the number of components in test 3 as well)
 # 5 extra tests for the loading options
-use Test::More tests => 2 + 6 * 24 + 5;
+# One test for components in inner packages
+use Test::More tests => 2 + 6 * 24 + 8 + 1;
 
 use strict;
 use warnings;
@@ -10,6 +11,7 @@ use File::Spec;
 use File::Path;
 
 my $libdir = 'test_trash';
+local @INC = @INC;
 unshift(@INC, $libdir);
 
 my $appclass = 'TestComponents';
@@ -40,7 +42,7 @@ my @components = (
     { type => 'View', prefix => 'View', name => 'Foo' },
 );
 
-sub write_component_file { 
+sub write_component_file {
   my ($dir_list, $module_name, $content) = @_;
 
   my $dir  = File::Spec->catdir(@$dir_list);
@@ -53,7 +55,7 @@ sub write_component_file {
 }
 
 sub make_component_file {
-    my ($type, $prefix, $name) = @_;
+    my ($libdir, $appclass, $type, $prefix, $name) = @_;
 
     my $compbase = "Catalyst::${type}";
     my $fullname = "${appclass}::${prefix}::${name}";
@@ -77,9 +79,13 @@ EOF
 }
 
 foreach my $component (@components) {
-    make_component_file($component->{type},
-                        $component->{prefix},
-                        $component->{name});
+    make_component_file(
+        $libdir,
+        $appclass,
+        $component->{type},
+        $component->{prefix},
+        $component->{name},
+    );
 }
 
 my $shut_up_deprecated_warnings = q{
@@ -137,9 +143,13 @@ $appclass = 'ExtraOptions';
 push @components, { type => 'View', prefix => 'Extra', name => 'Foo' };
 
 foreach my $component (@components) {
-    make_component_file($component->{type},
-                        $component->{prefix},
-                        $component->{name});
+    make_component_file(
+        $libdir,
+        $appclass,
+        $component->{type},
+        $component->{prefix},
+        $component->{name},
+    );
 }
 
 eval qq(
@@ -170,10 +180,13 @@ write_component_file([$libdir, $appclass, 'Model'], 'TopLevel', <<EOF);
 package ${appclass}::Model::TopLevel;
 use base 'Catalyst::Model';
 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;
 }
 
@@ -189,8 +202,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
@@ -198,5 +213,23 @@ 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";
+
+{
+  package InnerComponent::Controller::Test;
+  use base 'Catalyst::Controller';
+}
+
+$INC{'InnerComponent/Controller/Test.pm'} = 1;
+
+eval "package $appclass; use Catalyst; __PACKAGE__->setup";
+
+isa_ok($appclass->controller('Test'), 'Catalyst::Controller');
 
 rmtree($libdir);
similarity index 81%
rename from t/unit_core_component_mro.t
rename to t/aggregate/unit_core_component_mro.t
index a8699c3..8e9a064 100644 (file)
@@ -17,13 +17,13 @@ use warnings;
 }
 
 my $warn = '';
-{  
+{
   local $SIG{__WARN__} = sub {
-    $warn .= $_[0];  
+    $warn .= $_[0];
   };
   MyApp::MyComponent->COMPONENT('MyApp');
 }
 
-like($warn, qr/after Catalyst::Component in MyApp::Component/, 
+like($warn, qr/after Catalyst::Component in MyApp::Component/,
     'correct warning thrown');
 
similarity index 91%
rename from t/unit_core_log.t
rename to t/aggregate/unit_core_log.t
index 26a52d3..f488d48 100644 (file)
@@ -1,17 +1,12 @@
 use strict;
 use warnings;
 
-use Test::More tests => 23;
+use Test::More tests => 22;
 
-my $LOG;
+use Catalyst::Log;
 
-BEGIN {
-    chdir 't' if -d 't';
-    use lib '../lib';
-    $LOG = 'Catalyst::Log';
-    use_ok $LOG or die;
-}
-my @MESSAGES;
+local *Catalyst::Log::_send_to_log;
+local our @MESSAGES;
 {
     no warnings 'redefine';
     *Catalyst::Log::_send_to_log = sub {
@@ -20,6 +15,8 @@ my @MESSAGES;
     };
 }
 
+my $LOG = 'Catalyst::Log';
+
 can_ok $LOG, 'new';
 ok my $log = $LOG->new, '... and creating a new log object should succeed';
 isa_ok $log, $LOG, '... and the object it returns';
similarity index 84%
rename from t/unit_core_merge_config_hashes.t
rename to t/aggregate/unit_core_merge_config_hashes.t
index 53f8be2..1ac737b 100644 (file)
@@ -34,10 +34,10 @@ my @tests = (
     },
 );
 
-plan tests => scalar @tests + 1;
+plan tests => scalar @tests;
 
-use_ok('Catalyst');
+use Catalyst::Component;
 
 for my $test ( @ tests ) {
-    is_deeply( Catalyst->merge_config_hashes( @{ $test->{ given } } ), $test->{ expects } );
+    is_deeply( Catalyst::Component->merge_config_hashes( @{ $test->{ given } } ), $test->{ expects } );
 }
diff --git a/t/aggregate/unit_core_mvc.t b/t/aggregate/unit_core_mvc.t
new file mode 100644 (file)
index 0000000..b04c3a3
--- /dev/null
@@ -0,0 +1,227 @@
+use Test::More tests => 51;
+use strict;
+use warnings;
+
+use_ok('Catalyst');
+
+my @complist =
+  map { "MyMVCTestApp::$_"; }
+  qw/C::Controller M::Model V::View Controller::C Model::M View::V Controller::Model::Dummy::Model Model::Dummy::Model/;
+
+{
+
+    package MyMVCTestApp;
+
+    use base qw/Catalyst/;
+
+    __PACKAGE__->components( { map { ( ref($_)||$_ , $_ ) } @complist } );
+
+    my $thingie={};
+    bless $thingie, 'Some::Test::Object';
+    __PACKAGE__->components->{'MyMVCTestApp::Model::Test::Object'} = $thingie;
+
+    # allow $c->log->warn to work
+    __PACKAGE__->setup_log;
+}
+
+is( MyMVCTestApp->view('View'), 'MyMVCTestApp::V::View', 'V::View ok' );
+
+is( MyMVCTestApp->controller('Controller'),
+    'MyMVCTestApp::C::Controller', 'C::Controller ok' );
+
+is( MyMVCTestApp->model('Model'), 'MyMVCTestApp::M::Model', 'M::Model ok' );
+
+is( MyMVCTestApp->model('Dummy::Model'), 'MyMVCTestApp::Model::Dummy::Model', 'Model::Dummy::Model ok' );
+
+isa_ok( MyMVCTestApp->model('Test::Object'), 'Some::Test::Object', 'Test::Object ok' );
+
+is( MyMVCTestApp->controller('Model::Dummy::Model'), 'MyMVCTestApp::Controller::Model::Dummy::Model', 'Controller::Model::Dummy::Model ok' );
+
+is( MyMVCTestApp->view('V'), 'MyMVCTestApp::View::V', 'View::V ok' );
+
+is( MyMVCTestApp->controller('C'), 'MyMVCTestApp::Controller::C', 'Controller::C ok' );
+
+is( MyMVCTestApp->model('M'), 'MyMVCTestApp::Model::M', 'Model::M ok' );
+
+# failed search
+{
+    is( MyMVCTestApp->model('DNE'), undef, 'undef for invalid search' );
+}
+
+is_deeply( [ sort MyMVCTestApp->views ],
+           [ qw/V View/ ],
+           'views ok' );
+
+is_deeply( [ sort MyMVCTestApp->controllers ],
+           [ qw/C Controller Model::Dummy::Model/ ],
+           'controllers ok');
+
+is_deeply( [ sort MyMVCTestApp->models ],
+           [ qw/Dummy::Model M Model Test::Object/ ],
+           'models ok');
+
+{
+    my $warnings = 0;
+    no warnings 'redefine';
+    local *Catalyst::Log::warn = sub { $warnings++ };
+
+    like (MyMVCTestApp->view , qr/^MyMVCTestApp\::(V|View)\::/ , 'view() with no defaults returns *something*');
+    ok( $warnings, 'view() w/o a default is random, warnings thrown' );
+}
+
+is ( bless ({stash=>{current_view=>'V'}}, 'MyMVCTestApp')->view , 'MyMVCTestApp::View::V', 'current_view ok');
+
+my $view = bless {} , 'MyMVCTestApp::View::V';
+is ( bless ({stash=>{current_view_instance=> $view }}, 'MyMVCTestApp')->view , $view, 'current_view_instance ok');
+
+is ( bless ({stash=>{current_view_instance=> $view, current_view=>'MyMVCTestApp::V::View' }}, 'MyMVCTestApp')->view , $view,
+  'current_view_instance precedes current_view ok');
+
+{
+    my $warnings = 0;
+    no warnings 'redefine';
+    local *Catalyst::Log::warn = sub { $warnings++ };
+
+    ok( my $model = MyMVCTestApp->model );
+
+    ok( (($model =~ /^MyMVCTestApp\::(M|Model)\::/) ||
+        $model->isa('Some::Test::Object')),
+        'model() with no defaults returns *something*' );
+
+    ok( $warnings, 'model() w/o a default is random, warnings thrown' );
+}
+
+is ( bless ({stash=>{current_model=>'M'}}, 'MyMVCTestApp')->model , 'MyMVCTestApp::Model::M', 'current_model ok');
+
+my $model = bless {} , 'MyMVCTestApp::Model::M';
+is ( bless ({stash=>{current_model_instance=> $model }}, 'MyMVCTestApp')->model , $model, 'current_model_instance ok');
+
+is ( bless ({stash=>{current_model_instance=> $model, current_model=>'MyMVCTestApp::M::Model' }}, 'MyMVCTestApp')->model , $model,
+  'current_model_instance precedes current_model ok');
+
+MyMVCTestApp->config->{default_view} = 'V';
+is ( bless ({stash=>{}}, 'MyMVCTestApp')->view , 'MyMVCTestApp::View::V', 'default_view ok');
+is ( MyMVCTestApp->view , 'MyMVCTestApp::View::V', 'default_view in class method ok');
+
+MyMVCTestApp->config->{default_model} = 'M';
+is ( bless ({stash=>{}}, 'MyMVCTestApp')->model , 'MyMVCTestApp::Model::M', 'default_model ok');
+is ( MyMVCTestApp->model , 'MyMVCTestApp::Model::M', 'default_model in class method ok');
+
+# regexp behavior tests
+{
+    # is_deeply is used because regexp behavior means list context
+    is_deeply( [ MyMVCTestApp->view( qr{^V[ie]+w$} ) ], [ 'MyMVCTestApp::V::View' ], 'regexp view ok' );
+    is_deeply( [ MyMVCTestApp->controller( qr{Dummy\::Model$} ) ], [ 'MyMVCTestApp::Controller::Model::Dummy::Model' ], 'regexp controller ok' );
+    is_deeply( [ MyMVCTestApp->model( qr{Dum{2}y} ) ], [ 'MyMVCTestApp::Model::Dummy::Model' ], 'regexp model ok' );
+
+    # object w/ qr{}
+    is_deeply( [ MyMVCTestApp->model( qr{Test} ) ], [ MyMVCTestApp->components->{'MyMVCTestApp::Model::Test::Object'} ], 'Object returned' );
+
+    {
+        my $warnings = 0;
+        no warnings 'redefine';
+        local *Catalyst::Log::warn = sub { $warnings++ };
+
+        # object w/ regexp fallback
+        is_deeply( [ MyMVCTestApp->model( 'Test' ) ], [ MyMVCTestApp->components->{'MyMVCTestApp::Model::Test::Object'} ], 'Object returned' );
+        ok( $warnings, 'regexp fallback warnings' );
+    }
+
+    is_deeply( [ MyMVCTestApp->view('MyMVCTestApp::V::View$') ], [ 'MyMVCTestApp::V::View' ], 'Explicit return ok');
+    is_deeply( [ MyMVCTestApp->controller('MyMVCTestApp::C::Controller$') ], [ 'MyMVCTestApp::C::Controller' ], 'Explicit return ok');
+    is_deeply( [ MyMVCTestApp->model('MyMVCTestApp::M::Model$') ], [ 'MyMVCTestApp::M::Model' ], 'Explicit return ok');
+}
+
+{
+    my @expected = qw( MyMVCTestApp::C::Controller MyMVCTestApp::Controller::C );
+    is_deeply( [ sort MyMVCTestApp->controller( qr{^C} ) ], \@expected, 'multiple controller returns from regexp search' );
+}
+
+{
+    my @expected = qw( MyMVCTestApp::V::View MyMVCTestApp::View::V );
+    is_deeply( [ sort MyMVCTestApp->view( qr{^V} ) ], \@expected, 'multiple view returns from regexp search' );
+}
+
+{
+    my @expected = qw( MyMVCTestApp::M::Model MyMVCTestApp::Model::M );
+    is_deeply( [ sort MyMVCTestApp->model( qr{^M} ) ], \@expected, 'multiple model returns from regexp search' );
+}
+
+# failed search
+{
+    is( scalar MyMVCTestApp->controller( qr{DNE} ), 0, '0 results for failed search' );
+}
+
+#checking @args passed to ACCEPT_CONTEXT
+{
+    my $args;
+
+    {
+        no warnings 'once';
+        *MyMVCTestApp::Model::M::ACCEPT_CONTEXT = sub { my ($self, $c, @args) = @_; $args= \@args};
+        *MyMVCTestApp::View::V::ACCEPT_CONTEXT = sub { my ($self, $c, @args) = @_; $args= \@args};
+    }
+
+    my $c = bless {}, 'MyMVCTestApp';
+
+    # test accept-context with class rather than instance
+    MyMVCTestApp->model('M', qw/foo bar/);
+    is_deeply($args, [qw/foo bar/], 'MyMVCTestApp->model args passed to ACCEPT_CONTEXT ok');
+
+
+    $c->model('M', qw/foo bar/);
+    is_deeply($args, [qw/foo bar/], '$c->model args passed to ACCEPT_CONTEXT ok');
+
+    my $x = $c->view('V', qw/foo2 bar2/);
+    is_deeply($args, [qw/foo2 bar2/], '$c->view args passed to ACCEPT_CONTEXT ok');
+
+    # regexp fallback
+    $c->view('::View::V', qw/foo3 bar3/);
+    is_deeply($args, [qw/foo3 bar3/], 'args passed to ACCEPT_CONTEXT ok');
+
+
+}
+
+{
+    my $warn = '';
+    no warnings 'redefine';
+    local *Catalyst::Log::warn = sub { $warn .= $_[1] };
+
+    is_deeply (MyMVCTestApp->controller('MyMVCTestApp::Controller::C'),
+        MyMVCTestApp->components->{'MyMVCTestApp::Controller::C'},
+        'controller by fully qualified name ok');
+
+    # You probably meant $c->controller('C') instead of $c->controller({'MyMVCTestApp::Controller::C'})
+    my ($suggested_comp_name, $orig_comp_name) = $warn =~ /You probably meant (.*) instead of (.*) /;
+    isnt($suggested_comp_name, $orig_comp_name, 'suggested fix in warning for fully qualified component names makes sense' );
+}
+
+{
+    package MyApp::WithoutRegexFallback;
+
+    use base qw/Catalyst/;
+
+    __PACKAGE__->config( { disable_component_resolution_regex_fallback => 1 } );
+
+    __PACKAGE__->components( { map { ( ref($_)||$_ , $_ ) }
+        qw/MyApp::WithoutRegexFallback::Controller::Another::Foo/ } );
+
+    # allow $c->log->warn to work
+    __PACKAGE__->setup_log;
+}
+
+{
+    # test if non-regex component retrieval still works
+    is( MyApp::WithoutRegexFallback->controller('Another::Foo'),
+        'MyApp::WithoutRegexFallback::Controller::Another::Foo', 'controller Another::Foo found');
+}
+
+{
+    my $warnings = 0;
+    no warnings 'redefine';
+    local *Catalyst::Log::warn = sub { $warnings++ };
+
+    # try to get nonexisting object w/o regexp fallback
+    is( MyApp::WithoutRegexFallback->controller('Foo'), undef, 'no controller Foo found');
+    ok( !$warnings, 'no regexp fallback warnings' );
+}
similarity index 86%
rename from t/unit_core_plugin.t
rename to t/aggregate/unit_core_plugin.t
index 93d08d8..11cef84 100644 (file)
@@ -11,9 +11,8 @@ use lib 't/lib';
 
     package Faux::Plugin;
 
-    sub new { bless {}, shift }
-    my $count = 1;
-    sub count { $count++ }
+    sub new { bless { count => 1 }, shift }
+    sub count { shift->{count}++ }
 }
 
 my $warnings = 0;
@@ -21,6 +20,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 +42,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 +60,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';
+
diff --git a/t/aggregate/unit_core_script_cgi.t b/t/aggregate/unit_core_script_cgi.t
new file mode 100644 (file)
index 0000000..ba187e1
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use Test::More;
+use Test::Exception;
+
+use Catalyst::Script::CGI;
+
+local @ARGV;
+lives_ok {
+    Catalyst::Script::CGI->new_with_options(application_name => 'TestAppToTestScripts')->run;
+} "new_with_options";
+shift @TestAppToTestScripts::RUN_ARGS;
+is_deeply \@TestAppToTestScripts::RUN_ARGS, [], "no args";
+
+done_testing;
diff --git a/t/aggregate/unit_core_script_create.t b/t/aggregate/unit_core_script_create.t
new file mode 100644 (file)
index 0000000..588cfd5
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+use Test::Exception;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+{
+    package TestCreateScript;
+    use Moose;
+    extends 'Catalyst::Script::Create';
+    our $help;
+    sub _exit_with_usage { $help++ }
+}
+
+{
+    package TestHelperClass;
+    use Moose;
+
+    has 'newfiles' => ( is => 'ro', init_arg => '.newfiles' );
+    has 'mech' => ( is => 'ro' );
+    our @ARGS;
+    our %p;
+    sub mk_component {
+        my $self = shift;
+        @ARGS = @_;
+        %p = ( '.newfiles' => $self->newfiles, mech => $self->mech);
+        return $self->_mk_component_return;
+    }
+    sub _mk_component_return { 1 }
+}
+{
+    package TestHelperClass::False;
+    use Moose;
+    extends 'TestHelperClass';
+    sub _mk_component_return { 0 }
+}
+
+{
+    local $TestCreateScript::help;
+    local @ARGV;
+    lives_ok {
+        TestCreateScript->new_with_options(application_name => 'TestAppToTestScripts', helper_class => 'TestHelperClass')->run;
+    } "no argv";
+    ok $TestCreateScript::help, 'Exited with usage info';
+}
+{
+    local $TestCreateScript::help;
+    local @ARGV = 'foo';
+    local @TestHelperClass::ARGS;
+    local %TestHelperClass::p;
+    lives_ok {
+        TestCreateScript->new_with_options(application_name => 'TestAppToTestScripts', helper_class => 'TestHelperClass')->run;
+    } "with argv";
+    ok !$TestCreateScript::help, 'Did not exit with usage into';
+    is_deeply \@TestHelperClass::ARGS, ['TestAppToTestScripts', 'foo'], 'Args correct';
+    is_deeply \%TestHelperClass::p, { '.newfiles' => 1, mech => undef }, 'Params correct';
+}
+
+{
+    local $TestCreateScript::help;
+    local @ARGV = 'foo';
+    local @TestHelperClass::ARGS;
+    local %TestHelperClass::p;
+    lives_ok {
+        TestCreateScript->new_with_options(application_name => 'TestAppToTestScripts', helper_class => 'TestHelperClass::False')->run;
+    } "with argv";
+    ok $TestCreateScript::help, 'Did exit with usage into as mk_component returned false';
+    is_deeply \@TestHelperClass::ARGS, ['TestAppToTestScripts', 'foo'], 'Args correct';
+    is_deeply \%TestHelperClass::p, { '.newfiles' => 1, mech => undef }, 'Params correct';
+}
+
+done_testing;
diff --git a/t/aggregate/unit_core_script_fastcgi.t b/t/aggregate/unit_core_script_fastcgi.t
new file mode 100644 (file)
index 0000000..7d4da0f
--- /dev/null
@@ -0,0 +1,70 @@
+use strict;
+use warnings;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use Test::More;
+use Test::Exception;
+
+use Catalyst::Script::FastCGI;
+
+my $testopts;
+
+# Test default (no opts/args behaviour)
+testOption( [ qw// ], [undef, opthash()] );
+
+# listen socket
+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()] );
+
+# pidfile        -pidfile                  --pid --pidfile
+testOption( [ qw/--pidfile cat.pid/ ], [undef, opthash(pidfile => 'cat.pid')] );
+testOption( [ qw/--pid cat.pid/ ], [undef, opthash(pidfile => 'cat.pid')] );
+
+# manager
+testOption( [ qw/--manager foo::bar/ ], [undef, opthash(manager => 'foo::bar')] );
+testOption( [ qw/-M foo::bar/ ], [undef, opthash(manager => 'foo::bar')] );
+
+# keeperr
+testOption( [ qw/--keeperr/ ], [undef, opthash(keep_stderr => 1)] );
+testOption( [ qw/-e/ ], [undef, opthash(keep_stderr => 1)] );
+
+# nproc
+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 {
+    my ($argstring, $resultarray) = @_;
+
+    local @ARGV = @$argstring;
+    local @TestAppToTestScripts::RUN_ARGS;
+    lives_ok {
+        Catalyst::Script::FastCGI->new_with_options(application_name => 'TestAppToTestScripts')->run;
+    } "new_with_options";
+    # First element of RUN_ARGS will be the script name, which we don't care about
+    shift @TestAppToTestScripts::RUN_ARGS;
+    is_deeply \@TestAppToTestScripts::RUN_ARGS, $resultarray, "is_deeply comparison";
+}
+
+# Returns the hash expected when no flags are passed
+sub opthash {
+    return {
+        pidfile => undef,
+        keep_stderr => undef,
+        detach => undef,
+        nproc => undef,
+        manager => undef,
+        @_,
+    };
+}
diff --git a/t/aggregate/unit_core_script_help.t b/t/aggregate/unit_core_script_help.t
new file mode 100644 (file)
index 0000000..0287990
--- /dev/null
@@ -0,0 +1,31 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+use Test::Exception;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+{
+    package TestHelpScript;
+    use Moose;
+    with 'Catalyst::ScriptRole';
+    our $help;
+    sub _getopt_full_usage { $help++ }
+}
+
+test('-h');
+test('--help');
+test('-?');
+
+sub test {
+    local $TestHelpScript::help;
+    local @ARGV = (@_);
+    lives_ok {
+        TestHelpScript->new_with_options(application_name => 'TestAppToTestScripts')->run;
+    } 'Lives';
+    ok $TestHelpScript::help, 'Got help';
+}
+
+done_testing;
diff --git a/t/aggregate/unit_core_script_server.t b/t/aggregate/unit_core_script_server.t
new file mode 100644 (file)
index 0000000..694b75a
--- /dev/null
@@ -0,0 +1,116 @@
+use strict;
+use warnings;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use Test::More;
+use Test::Exception;
+
+use Catalyst::Script::Server;
+
+my $testopts;
+
+# Test default (no opts/args behaviour)
+testOption( [ qw// ], ['3000', 'localhost', opthash()] );
+
+# Old version supports long format opts with either one or two dashes.  New version only supports two.
+#                Old                       New
+# help           -? -help --help           -? --help
+# debug          -d -debug --debug         -d --debug
+# host           -host --host              --host
+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()] );
+
+# fork           -f -fork --fork           -f --fork
+testOption( [ qw/--fork/ ], ['3000', 'localhost', opthash(fork => 1)] );
+testOption( [ qw/-f/ ], ['3000', 'localhost', 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")] );
+
+# keepalive      -k -keepalive --keepalive -k --keepalive
+testOption( [ qw/-k/ ], ['3000', 'localhost', opthash(keepalive => 1)] );
+testOption( [ qw/--keepalive/ ], ['3000', 'localhost', 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)] );
+
+# background     -background               --bg --background
+testOption( [ qw/--background/ ], ['3000', 'localhost', opthash(background => 1)] );
+testOption( [ qw/--bg/ ], ['3000', 'localhost', opthash(background => 1)] );
+
+# restart        -r -restart --restart     -R --restart
+testRestart( ['-r'], 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) );
+
+# restart dir    -restartdirectory         --rdir --restart_directory
+testRestart( ['-r', '--rdir', 'root'], restartopthash(directories => ['root']) );
+testRestart( ['-r', '--rdir', 'root', '--rdir', 'lib'], restartopthash(directories => ['root', 'lib']) );
+testRestart( ['-r', '--restart_directory', 'root'], restartopthash(directories => ['root']) );
+
+# restart regex  -rr -restartregex         --rr --restart_regex
+testRestart( ['-r', '--rr', 'foo'], restartopthash(filter => qr/foo/) );
+testRestart( ['-r', '--restart_regex', 'foo'], restartopthash(filter => qr/foo/) );
+
+done_testing;
+
+sub testOption {
+    my ($argstring, $resultarray) = @_;
+    my $app = _build_testapp($argstring);
+    lives_ok {
+        $app->run;
+    };
+    # First element of RUN_ARGS will be the script name, which we don't care about
+    shift @TestAppToTestScripts::RUN_ARGS;
+    is_deeply \@TestAppToTestScripts::RUN_ARGS, $resultarray, "is_deeply comparison " . join(' ', @$argstring);
+}
+
+sub testRestart {
+    my ($argstring, $resultarray) = @_;
+    my $app = _build_testapp($argstring);
+    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';
+    is_deeply $args, $resultarray, "is_deeply comparison of restarter args " . join(' ', @$argstring);
+}
+
+sub _build_testapp {
+    my ($argstring, $resultarray) = @_;
+
+    local @ARGV = @$argstring;
+    local @TestAppToTestScripts::RUN_ARGS;
+    my $i;
+    lives_ok {
+        $i = Catalyst::Script::Server->new_with_options(application_name => 'TestAppToTestScripts');
+    } "new_with_options " . join(' ', @$argstring);;
+    ok $i;
+    return $i;
+}
+
+# Returns the hash expected when no flags are passed
+sub opthash {
+    return {
+        'pidfile' => undef,
+        'fork' => 0,
+        'follow_symlinks' => 0,
+        'background' => 0,
+        'keepalive' => 0,
+        @_,
+    };
+}
+
+sub restartopthash {
+    return {
+        follow_symlinks => 0,
+        @_,
+    };
+}
diff --git a/t/aggregate/unit_core_script_test.t b/t/aggregate/unit_core_script_test.t
new file mode 100644 (file)
index 0000000..5f56681
--- /dev/null
@@ -0,0 +1,54 @@
+use strict;
+use warnings;
+
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use Test::More;
+use Test::Exception;
+
+use Catalyst::Script::Test;
+use File::Temp qw/tempfile/;
+use IO::Handle;
+
+is run_test('/'), "root index\n", 'correct content printed';
+is run_test('/moose/get_attribute'), "42\n", 'Correct content printed for non root action';
+
+done_testing;
+
+sub run_test {
+    my $url = shift;
+
+    my ($fh, $fn) = tempfile();
+
+    binmode( $fh );
+    binmode( STDOUT );
+
+    {
+        local @ARGV = ($url);
+        my $i;
+        lives_ok {
+            $i = Catalyst::Script::Test->new_with_options(application_name => 'TestApp');
+        } "new_with_options";
+        ok $i;
+        my $saved;
+        open( $saved, '<&'. STDIN->fileno )
+              or croak("Can't dup stdin: $!");
+        open( STDOUT, '>&='. $fh->fileno )
+            or croak("Can't open stdout: $!");
+        eval { $i->run };
+        ok !$@, 'Ran ok';
+
+        STDOUT->flush
+            or croak("Can't flush stdout: $!");
+
+        open( STDOUT, '>&'. fileno($saved) )
+            or croak("Can't restore stdout: $!");
+    }
+
+    my $data = do { my $fh; open($fh, '<', $fn) or die $!; local $/; <$fh>; };
+    $fh = undef;
+    unlink $fn if -r $fn;
+
+    return $data;
+}
diff --git a/t/aggregate/unit_core_scriptrunner.t b/t/aggregate/unit_core_scriptrunner.t
new file mode 100644 (file)
index 0000000..d9af3bc
--- /dev/null
@@ -0,0 +1,24 @@
+use strict;
+use warnings;
+use Test::More;
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+
+use_ok('Catalyst::ScriptRunner');
+
+is Catalyst::ScriptRunner->run('ScriptTestApp', 'Foo'), 'ScriptTestApp::Script::Foo',
+    'Script existing only in app';
+is Catalyst::ScriptRunner->run('ScriptTestApp', 'Bar'), 'ScriptTestApp::Script::Bar',
+    'Script existing in both app and Catalyst - prefers app';
+is Catalyst::ScriptRunner->run('ScriptTestApp', 'Baz'), 'Catalyst::Script::Baz',
+    'Script existing only in Catalyst';
+# +1 test for the params passed to new_with_options in t/lib/Catalyst/Script/Baz.pm
+{
+    my $warnings = '';
+    local $SIG{__WARN__} = sub { $warnings .= shift };
+    is 'Catalyst::Script::CompileTest', Catalyst::ScriptRunner->run('ScriptTestApp', 'CompileTest');
+    like $warnings, qr/Does not compile/;
+    like $warnings, qr/Could not load ScriptTestApp::Script::CompileTest - falling back to Catalyst::Script::CompileTest/;
+}
+
+done_testing;
similarity index 80%
rename from t/unit_core_setup.t
rename to t/aggregate/unit_core_setup.t
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';
 
similarity index 76%
rename from t/unit_core_setup_log.t
rename to t/aggregate/unit_core_setup_log.t
index 401ea99..e2dba17 100644 (file)
@@ -8,7 +8,6 @@ use Catalyst ();
 
 sub mock_app {
     my $name = shift;
-    print "Setting up mock application: $name\n";
     my $meta = Moose->init_meta( for_class => $name );
     $meta->superclasses('Catalyst');
     return $meta->name;
@@ -27,10 +26,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 +46,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 +60,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 +74,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 +87,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,
similarity index 62%
rename from t/unit_core_setup_stats.t
rename to t/aggregate/unit_core_setup_stats.t
index 8cc979f..9aca059 100644 (file)
@@ -6,7 +6,7 @@ use Class::MOP::Class;
 
 use Catalyst ();
 
-my %log_messages; # TODO - Test log messages as expected.
+local our %log_messages; # TODO - Test log messages as expected.
 my $mock_log = Class::MOP::Class->create_anon_class(
     methods => {
         map { my $level = $_;
@@ -21,41 +21,48 @@ my $mock_log = Class::MOP::Class->create_anon_class(
 
 sub mock_app {
     my $name = shift;
+    my $mock_log = 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 }); 
+    $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', $mock_log);
     $app->setup_stats();
     ok !$app->use_stats, 'stats off by default';
 }
 {
-    my $app = mock_app('TestStats');
+    my $app = mock_app('TestAppStats', $mock_log);
     $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', $mock_log);
     $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', $mock_log);
     $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', $mock_log);
     $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)';
similarity index 99%
rename from t/unit_core_uri_for.t
rename to t/aggregate/unit_core_uri_for.t
index 3dd3a69..170e91b 100644 (file)
@@ -46,7 +46,7 @@ is(
 is (Catalyst::uri_for( $context, '/bar/wibble?' )->as_string,
    'http://127.0.0.1/foo/bar/wibble%3F', 'Question Mark gets encoded'
 );
-   
+
 is( Catalyst::uri_for( $context, qw/bar wibble?/, 'with space' )->as_string,
     'http://127.0.0.1/foo/yada/bar/wibble%3F/with%20space', 'Space gets encoded'
 );
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");
diff --git a/t/aggregate/unit_dispatcher_requestargs_restore.t b/t/aggregate/unit_dispatcher_requestargs_restore.t
new file mode 100644 (file)
index 0000000..9c4b7fa
--- /dev/null
@@ -0,0 +1,21 @@
+# Insane test case for the behavior needed by Plugin::Auhorization::ACL
+
+# We have to localise $c->request->{arguments} in
+# Catalyst::Dispatcher::_do_forward, rather than using save and restore,
+# as otherwise, the calling $c->detach on an action which says
+# die $Catalyst:DETACH causes the request arguments to not get restored,
+# and therefore sub gorch gets the wrong string $frozjob parameter.
+
+# Please feel free to break this behavior once a sane hook for safely
+# executing another action from the dispatcher (i.e. wrapping actions)
+# is present, so that the Authorization::ACL plugin can be re-written
+# to not be full of such crazy shit.
+
+use strict;
+use warnings;
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+use Catalyst::Test 'ACLTestApp';
+use Test::More tests => 1;
+
+request('http://localhost/gorch/wozzle');
similarity index 94%
rename from t/unit_load_catalyst_test.t
rename to t/aggregate/unit_load_catalyst_test.t
index ffa5655..fa8144c 100644 (file)
@@ -4,10 +4,10 @@ use strict;
 use warnings;
 
 use FindBin;
-use lib         "$FindBin::Bin/lib";
-use Test::More  tests => 59;
+use lib         "$FindBin::Bin/../lib";
+use Test::More  tests => 61;
 use FindBin qw/$Bin/;
-use lib "$Bin/lib";
+use lib "$Bin/../lib";
 use Catalyst::Utils;
 use HTTP::Request::Common;
 use Test::Exception;
@@ -89,6 +89,9 @@ use_ok( $Class );
                                 "               Content recorded in response" );
         ok( $c->stash,          "               Stash accessible" );
         ok( $c->action,         "               Action object accessible" );
+        ok( $res->request,      "               Response has request object" );
+        lives_and { is( $res->request->uri, $Url) }
+                                "               Request object has correct url";
     } }
 }
 
diff --git a/t/aggregate/unit_metaclass_compat_non_moose_controller.t b/t/aggregate/unit_metaclass_compat_non_moose_controller.t
new file mode 100644 (file)
index 0000000..1672a18
--- /dev/null
@@ -0,0 +1,19 @@
+use strict;
+use warnings;
+
+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
+# f2391d17574eff81d911b97be15ea51080500003
+# after which the evil kludge in core can die in a fire.
+
+lives_ok {
+    TestAppNonMooseController::ControllerBase->get_action_methods
+} 'Base class->get_action_methods ok when sub class initialized first';
+
similarity index 95%
rename from t/unit_utils_env_value.t
rename to t/aggregate/unit_utils_env_value.t
index 015b455..5dd92cf 100644 (file)
@@ -1,9 +1,9 @@
 use strict;
 use warnings;
 
-use Test::More tests => 5;
+use Test::More tests => 4;
 
-BEGIN { use_ok("Catalyst::Utils") }
+use Catalyst::Utils;
 
 ##############################################################################
 ### No env vars defined
similarity index 93%
rename from t/unit_utils_prefix.t
rename to t/aggregate/unit_utils_prefix.t
index a1b7efa..506fbc2 100644 (file)
@@ -3,11 +3,11 @@
 use strict;
 use warnings;
 
-use Test::More tests => 9;
+use Test::More tests => 8;
 
 use lib "t/lib";
 
-BEGIN { use_ok("Catalyst::Utils") };
+use Catalyst::Utils;
 
 is( Catalyst::Utils::class2prefix('MyApp::V::Foo::Bar'), 'foo/bar', 'class2prefix works with M/V/C' );
 
similarity index 90%
rename from t/unit_utils_request.t
rename to t/aggregate/unit_utils_request.t
index ce74d55..e02791b 100644 (file)
@@ -1,9 +1,9 @@
 use strict;
 use warnings;
 
-use Test::More tests => 5;
+use Test::More tests => 4;
 
-use_ok('Catalyst::Utils');
+use Catalyst::Utils;
 
 {
     my $url = "/dump";
diff --git a/t/aggregate/utf8_content_length.t b/t/aggregate/utf8_content_length.t
new file mode 100644 (file)
index 0000000..86297e8
--- /dev/null
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+use FindBin qw/$Bin/;
+use lib "$Bin/../lib";
+use File::Spec;
+use Test::More;
+
+use Catalyst::Test qw/TestAppEncoding/;
+
+if ( $ENV{CATALYST_SERVER} ) {
+    plan skip_all => 'This test does not run live';
+    exit 0;
+}
+
+my $fn = "$Bin/../catalyst_130pix.gif";
+ok -r $fn, 'Can read catalyst_130pix.gif';
+my $size = -s $fn;
+{
+    my $r = request('/binary');
+    is $r->code, 200, '/binary OK';
+    is $r->header('Content-Length'), $size, '/binary correct content length';
+}
+{
+    my $r = request('/binary_utf8');
+    is $r->code, 200, '/binary_utf8 OK';
+    is $r->header('Content-Length'), $size, '/binary_utf8 correct content length';
+}
+
+done_testing;
+
similarity index 61%
rename from t/optional_http-server.t
rename to t/author/http-server.t
index 60f9259..8f60174 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' );
 
diff --git a/t/author/notabs.t b/t/author/notabs.t
new file mode 100644 (file)
index 0000000..5cd3ae0
--- /dev/null
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+
+use File::Spec;
+use FindBin ();
+use Test::More;
+use Test::NoTabs;
+
+all_perl_files_ok(qw/lib/);
+
diff --git a/t/author/pod.t b/t/author/pod.t
new file mode 100644 (file)
index 0000000..f908f73
--- /dev/null
@@ -0,0 +1,8 @@
+use strict;
+use warnings;
+use Test::More;
+
+use Test::Pod 1.14;
+
+all_pod_files_ok();
+
diff --git a/t/author/podcoverage.t b/t/author/podcoverage.t
new file mode 100644 (file)
index 0000000..e8730de
--- /dev/null
@@ -0,0 +1,13 @@
+use strict;
+use warnings;
+use Test::More;
+
+use Pod::Coverage 0.19;
+use Test::Pod::Coverage 1.04;
+
+all_pod_coverage_ok(
+  {
+    also_private => ['BUILD']
+  }
+);
+
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..8c8c0c2
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use FindBin qw/$Bin/;
+use lib "$Bin/lib";
+use Test::More tests => 1;
+use Test::Exception;
+
+lives_ok {
+    require TestAppClassExceptionSimpleTest;
+} 'Can load application';
index cfb5adf..d9f90e0 100644 (file)
@@ -9,13 +9,18 @@ use Test::More tests => 4;
 my $warnings;
 BEGIN { # Do this at compile time in case we generate a warning when use
         # DeprecatedTestApp
-    $SIG{__WARN__} = sub { $warnings++ if $_[0] =~ /trying to use NEXT/ };
+    $SIG{__WARN__} = sub {
+        $warnings++ if $_[0] =~ /uses NEXT, which is deprecated/;
+        $warnings++ if $_[0] =~ /trying to use NEXT, which is deprecated/;
+    };
 }
 use Catalyst; # Cause catalyst to be used so I can fiddle with the logging.
 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++;
diff --git a/t/deprecated_appclass_action_warnings.t b/t/deprecated_appclass_action_warnings.t
new file mode 100644 (file)
index 0000000..f25d8d5
--- /dev/null
@@ -0,0 +1,18 @@
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More;
+use Catalyst::Test 'DeprecatedActionsInAppClassTestApp';
+
+plan tests => 3;
+
+my $warnings;
+my $logger = DeprecatedActionsInAppClassTestApp::Log->new;
+Catalyst->log($logger);
+
+ok( my $response = request('http://localhost/foo'), 'Request' );
+ok( $response->is_success, 'Response Successful 2xx' );
+is( $DeprecatedActionsInAppClassTestApp::Log::warnings, 1, 'Get the appclass action warning' );
\ No newline at end of file
diff --git a/t/lib/ACLTestApp.pm b/t/lib/ACLTestApp.pm
new file mode 100644 (file)
index 0000000..ec87027
--- /dev/null
@@ -0,0 +1,26 @@
+package ACLTestApp;
+use Test::More;
+
+use strict;
+use warnings;
+use MRO::Compat;
+use Scalar::Util ();
+
+use base qw/Catalyst Catalyst::Controller/;
+use Catalyst qw//;
+
+sub execute {
+    my $c = shift;
+    my ( $class, $action ) = @_;
+
+    if ( Scalar::Util::blessed($action)
+        and $action->name ne "foobar" ) {
+       eval { $c->detach( 'foobar', [$action, 'foo'] ) };
+    }
+
+    $c->next::method( @_ );
+}
+
+__PACKAGE__->setup;
+
+1;
diff --git a/t/lib/ACLTestApp/Controller/Root.pm b/t/lib/ACLTestApp/Controller/Root.pm
new file mode 100644 (file)
index 0000000..a1aa83b
--- /dev/null
@@ -0,0 +1,18 @@
+package ACLTestApp::Controller::Root;
+use Test::More;
+
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+sub foobar : Private {
+    die $Catalyst::DETACH;
+}
+
+sub gorch : Local {
+    my ( $self, $c, $frozjob ) = @_;
+    is $frozjob, 'wozzle';
+    $c->res->body("gorch");
+}
+
+1;
index 688ad21..7453248 100644 (file)
@@ -2,7 +2,6 @@ package Catalyst::Plugin::Test::Deprecated;
 
 use strict;
 use warnings;
-use NEXT;
 
 sub prepare {
     my $class = shift;
index b620c5e..f4f835b 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use warnings;
 use MRO::Compat;
 
-use base qw/Catalyst::Controller Class::Data::Inheritable/;
+use base qw/Class::Data::Inheritable/;
 
  __PACKAGE__->mk_classdata('ran_setup');
 
@@ -22,26 +22,14 @@ sub prepare {
     return $c;
 }
 
-# Note: This is horrible, but Catalyst::Plugin::Server forces the body to
+# Note: Catalyst::Plugin::Server forces the body to
 #       be parsed, by calling the $c->req->body method in prepare_action.
 #       We need to test this, as this was broken by 5.80. See also
-#       t/aggregate/live_engine_request_body.t. Better ways to test this
-#       appreciated if you have suggestions :)
-{
-    my $have_req_body = 0;
-    sub prepare_action {
-        my $c = shift;
-        $have_req_body++ if $c->req->body;
-        $c->next::method(@_);
-    }
-    sub have_req_body_in_prepare_action : Local {
-        my ($self, $c) = @_;
-        $c->res->body($have_req_body);
-    }
-}
-
-sub end : Private {
-    my ($self,$c) = @_;
+#       t/aggregate/live_engine_request_body.t.
+sub prepare_action {
+    my $c = shift;
+    $c->res->header('X-Have-Request-Body', 1) if $c->req->body;
+    $c->next::method(@_);
 }
 
 1;
diff --git a/t/lib/Catalyst/Script/Bar.pm b/t/lib/Catalyst/Script/Bar.pm
new file mode 100644 (file)
index 0000000..18e699c
--- /dev/null
@@ -0,0 +1,9 @@
+package Catalyst::Script::Bar;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+1;
diff --git a/t/lib/Catalyst/Script/Baz.pm b/t/lib/Catalyst/Script/Baz.pm
new file mode 100644 (file)
index 0000000..d699fe6
--- /dev/null
@@ -0,0 +1,16 @@
+package Catalyst::Script::Baz;
+use Moose;
+use namespace::autoclean;
+
+use Test::More;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+after new_with_options => sub {
+    my ($self, %args) = @_;
+    is_deeply \%args, { application_name => 'ScriptTestApp' }, 'App name correct';
+};
+
+1;
diff --git a/t/lib/Catalyst/Script/CompileTest.pm b/t/lib/Catalyst/Script/CompileTest.pm
new file mode 100644 (file)
index 0000000..df81247
--- /dev/null
@@ -0,0 +1,16 @@
+package Catalyst::Script::CompileTest;
+use Moose;
+use namespace::autoclean;
+
+use Test::More;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+after new_with_options => sub {
+    my ($self, %args) = @_;
+    is_deeply \%args, { application_name => 'ScriptTestApp' }, 'App name correct';
+};
+
+1;
diff --git a/t/lib/DeprecatedActionsInAppClassTestApp.pm b/t/lib/DeprecatedActionsInAppClassTestApp.pm
new file mode 100644 (file)
index 0000000..9c870b0
--- /dev/null
@@ -0,0 +1,30 @@
+package DeprecatedActionsInAppClassTestApp;
+
+use strict;
+use warnings;
+use Catalyst;
+
+our $VERSION = '0.01';
+
+__PACKAGE__->config( name => 'DeprecatedActionsInAppClassTestApp', root => '/some/dir' );
+__PACKAGE__->log(DeprecatedActionsInAppClassTestApp::Log->new);
+__PACKAGE__->setup;
+
+sub foo : Local {
+    my ($self, $c) = @_;
+    $c->res->body('OK');
+}
+
+package DeprecatedActionsInAppClassTestApp::Log;
+use strict;
+use warnings;
+use base qw/Catalyst::Log/;
+
+our $warnings;
+
+sub warn {
+    my ($self, $warning) = @_;
+    $warnings++ if $warning =~ /action methods .+ found defined/i;
+}
+
+1;
index c476736..1031586 100644 (file)
@@ -6,48 +6,6 @@ use Catalyst qw(
         +TestApp::Plugin::FullyQualified
         );
 
-sub compile_time_plugins : Local {
-    my ( $self, $c ) = @_;
-
-    isa_ok $c, 'Catalyst::Plugin::Test::Plugin';
-    isa_ok $c, 'TestApp::Plugin::FullyQualified';
-
-    can_ok $c, 'registered_plugins';
-    $c->_test_plugins;
-
-    $c->res->body("ok");
-}
-
-sub run_time_plugins : Local {
-    my ( $self, $c ) = @_;
-
-    $c->_test_plugins;
-    my $faux_plugin = 'Faux::Plugin';
-
-# Trick perl into thinking the plugin is already loaded
-    $INC{'Faux/Plugin.pm'} = 1;
-
-    __PACKAGE__->plugin( faux => $faux_plugin );
-
-    isa_ok $c, 'Catalyst::Plugin::Test::Plugin';
-    isa_ok $c, 'TestApp::Plugin::FullyQualified';
-    ok !$c->isa($faux_plugin),
-    '... and it should not inherit from the instant plugin';
-    can_ok $c, 'faux';
-    is $c->faux->count, 1, '... and it should behave correctly';
-    is_deeply [ $c->registered_plugins ],
-    [
-        qw/Catalyst::Plugin::Test::Plugin
-        Faux::Plugin
-        TestApp::Plugin::FullyQualified/
-        ],
-    'registered_plugins() should report all plugins';
-    ok $c->registered_plugins('Faux::Plugin'),
-    '... and even the specific instant plugin';
-
-    $c->res->body("ok");
-}
-
 sub _test_plugins {
     my $c = shift;
     is_deeply [ $c->registered_plugins ],
diff --git a/t/lib/PluginTestApp/Controller/Root.pm b/t/lib/PluginTestApp/Controller/Root.pm
new file mode 100644 (file)
index 0000000..5358074
--- /dev/null
@@ -0,0 +1,55 @@
+package PluginTestApp::Controller::Root;
+use Test::More;
+
+use base 'Catalyst::Controller';
+
+#use Catalyst qw(
+#        Test::Plugin
+#        +TestApp::Plugin::FullyQualified
+#        );
+
+__PACKAGE__->config->{namespace} = '';
+
+sub compile_time_plugins : Local {
+    my ( $self, $c ) = @_;
+
+    isa_ok $c, 'Catalyst::Plugin::Test::Plugin';
+    isa_ok $c, 'TestApp::Plugin::FullyQualified';
+
+    can_ok $c, 'registered_plugins';
+    $c->_test_plugins;
+
+    $c->res->body("ok");
+}
+
+sub run_time_plugins : Local {
+    my ( $self, $c ) = @_;
+
+    $c->_test_plugins;
+    my $faux_plugin = 'Faux::Plugin';
+
+# Trick perl into thinking the plugin is already loaded
+    $INC{'Faux/Plugin.pm'} = 1;
+
+    ref($c)->plugin( faux => $faux_plugin );
+
+    isa_ok $c, 'Catalyst::Plugin::Test::Plugin';
+    isa_ok $c, 'TestApp::Plugin::FullyQualified';
+    ok !$c->isa($faux_plugin),
+    '... and it should not inherit from the instant plugin';
+    can_ok $c, 'faux';
+    is $c->faux->count, 1, '... and it should behave correctly';
+    is_deeply [ $c->registered_plugins ],
+    [
+        qw/Catalyst::Plugin::Test::Plugin
+        Faux::Plugin
+        TestApp::Plugin::FullyQualified/
+        ],
+    'registered_plugins() should report all plugins';
+    ok $c->registered_plugins('Faux::Plugin'),
+    '... and even the specific instant plugin';
+
+    $c->res->body("ok");
+}
+
+1;
diff --git a/t/lib/ScriptTestApp/Script/Bar.pm b/t/lib/ScriptTestApp/Script/Bar.pm
new file mode 100644 (file)
index 0000000..9617441
--- /dev/null
@@ -0,0 +1,9 @@
+package ScriptTestApp::Script::Bar;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+1;
diff --git a/t/lib/ScriptTestApp/Script/CompileTest.pm b/t/lib/ScriptTestApp/Script/CompileTest.pm
new file mode 100644 (file)
index 0000000..5d4b89c
--- /dev/null
@@ -0,0 +1,7 @@
+package ScriptTestApp::Script::CompileTest;
+use Moose;
+use namespace::autoclean;
+
+die("Does not compile");
+
+1;
diff --git a/t/lib/ScriptTestApp/Script/Foo.pm b/t/lib/ScriptTestApp/Script/Foo.pm
new file mode 100644 (file)
index 0000000..8d61c63
--- /dev/null
@@ -0,0 +1,9 @@
+package ScriptTestApp::Script::Foo;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+1;
index e14e3dc..a2fc0b2 100644 (file)
@@ -41,16 +41,6 @@ sub count_leaks {
 
 TestApp->setup;
 
-sub index : Private {
-    my ( $self, $c ) = @_;
-    $c->res->body('root index');
-}
-
-sub global_action : Private {
-    my ( $self, $c ) = @_;
-    $c->forward('TestApp::View::Dump::Request');
-}
-
 sub execute {
     my $c      = shift;
     my $class  = ref( $c->component( $_[0] ) ) || $_[0];
@@ -77,7 +67,7 @@ sub execute {
             @executed
         );
     }
-
+    no warnings 'recursion';
     return $c->SUPER::execute(@_);
 }
 
@@ -92,24 +82,6 @@ sub finalize_error {
     $c->res->body( 'FATAL ERROR: ' . join( ', ', @{ $c->error } ) );
 }
 
-sub class_forward_test_method :Private {
-    my ( $self, $c ) = @_;
-    $c->response->headers->header( 'X-Class-Forward-Test-Method' => 1 );
-}
-
-sub loop_test : Local {
-    my ( $self, $c ) = @_;
-
-    for( 1..1001 ) {
-        $c->forward( 'class_forward_test_method' );
-    }
-}
-
-sub recursion_test : Local {
-    my ( $self, $c ) = @_;
-    $c->forward( 'recursion_test' );
-}
-
 {
     no warnings 'redefine';
     sub Catalyst::Log::error { }
index 5a83aee..1240b0e 100644 (file)
@@ -9,6 +9,9 @@ sub execute {
     my $self = shift;
     my ( $controller, $c, $test ) = @_;
     $c->res->header( 'X-TestAppActionTestMyAction', 'MyAction works' );
+    $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 64de556..cbba762 100644 (file)
@@ -204,6 +204,13 @@ sub return_arg_decoded : Chained('/') PathPart('chained/return_arg_decoded') Arg
     $c->req->args([ map { decode_entities($_) } @{ $c->req->args }]);
 }
 
+sub roundtrip_urifor : Chained('/') PathPart('chained/roundtrip_urifor') CaptureArgs(1) {}
+sub roundtrip_urifor_end : Chained('roundtrip_urifor') PathPart('') Args(1) {
+    my ($self, $c) = @_;
+    # This should round-trip, always - i.e. the uri you put in should come back out.
+    $c->res->body($c->uri_for($c->action, $c->req->captures, @{$c->req->args}, $c->req->parameters));
+    $c->stash->{no_end} = 1;
+}
 
 sub end :Private {
   my ($self, $c) = @_;
diff --git a/t/lib/TestApp/Controller/Action/Chained/CaptureArgs.pm b/t/lib/TestApp/Controller/Action/Chained/CaptureArgs.pm
new file mode 100644 (file)
index 0000000..fb8320e
--- /dev/null
@@ -0,0 +1,60 @@
+package TestApp::Controller::Action::Chained::CaptureArgs;
+use warnings;
+use strict;
+
+use base qw( Catalyst::Controller );
+
+#
+#   This controller builds two patterns of URI:
+#      /captureargs/*/*
+#      /captureargs/*/*/edit
+#      /captureargs/*
+#      /captureargs/*/edit
+#   It will output the arguments they got passed to @_ after the
+#   context object. 
+#   /captureargs/one/edit should not dispatch to
+#   /captureargs/*/*
+
+sub base  :Chained('/') PathPart('captureargs') CaptureArgs(0) {
+    my ( $self, $c, $arg ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'base';
+}
+
+sub two_args :Chained('base') PathPart('') CaptureArgs(2) {
+    my ( $self, $c, $arg1, $arg2 ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'two_args', $arg1, $arg2;
+}
+
+sub one_arg :Chained('base') ParthPart('') CaptureArgs(1) {
+    my ( $self, $c, $arg ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'one_arg', $arg;
+}
+
+sub edit_two_args  :Chained('two_args') PathPart('edit') Args(0) {
+    my ( $self, $c ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'edit_two_args';
+}
+
+sub edit_one_arg :Chained('one_arg') PathPart('edit') Args(0) {
+    my ( $self, $c ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'edit_one_arg';
+}
+
+sub view_two_args :Chained('two_args') PathPart('') Args(0) {
+    my ( $self, $c ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'view_two_args';
+}
+
+sub view_one_arg :Chained('one_arg') PathPart('') Args(0) {
+    my ( $self, $c ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'view_one_arg';
+}
+
+
+sub end : Private {
+    my ( $self, $c ) = @_;
+    no warnings 'uninitialized';
+    $c->response->body( join '; ', @{ $c->stash->{ passed_args } } );
+}
+
+1;
index d067223..9d384ed 100644 (file)
@@ -8,27 +8,27 @@ sub default : Private {
     $c->res->output('access denied');
 }
 
-sub one : Private { 
+sub one : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
 
-sub two : Private Relative {
+sub two : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
 
-sub three : Private Absolute {
+sub three : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
 
-sub four : Private Path('/action/private/four') {
+sub four : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
 
-sub five : Private Path('five') {
+sub five : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
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;
diff --git a/t/lib/TestApp/Controller/Anon.pm b/t/lib/TestApp/Controller/Anon.pm
new file mode 100644 (file)
index 0000000..68b4fd6
--- /dev/null
@@ -0,0 +1,40 @@
+package Anon::Trait;
+use Moose::Role -traits => 'MethodAttributes'; # Needed for role composition to work correctly with anon classes.
+
+after test => sub {
+    my ($self, $c) = @_;
+    $c->res->header('X-Anon-Trait-Applied', 1);
+};
+
+no Moose::Role;
+
+package TestApp::Controller::Anon;
+use Moose;
+use Moose::Util qw/find_meta/;
+use namespace::clean -except => 'meta';
+BEGIN { extends 'Catalyst::Controller' };
+
+sub COMPONENT { # Don't do this yourself, use CatalystX::Component::Traits!
+    my ($class, $app, $args) = @_;
+
+    my $meta = $class->meta->create_anon_class(
+            superclasses => [ $class->meta->name ],
+            roles        => ['Anon::Trait'],
+            cache        => 1,
+    );
+    # Special move as the methodattributes trait has changed our metaclass..
+    $meta = find_meta($meta->name);
+
+    $meta->add_method('meta' => sub { $meta });
+    $class = $meta->name;
+    $class->new($app, $args);
+}
+
+sub test : Local ActionClass('+TestApp::Action::TestMyAction') {
+    my ($self, $c) = @_;
+    $c->res->header('X-Component-Name-Controller', $self->catalyst_component_name);
+    $c->res->body('It works');
+}
+
+__PACKAGE__->meta->make_immutable;
+
index fcbdc5e..69431b3 100644 (file)
@@ -3,7 +3,7 @@ package TestApp::Controller::Dump;
 use strict;
 use base 'Catalyst::Controller';
 
-sub default : Action Private {
+sub default : Action {
     my ( $self, $c ) = @_;
     $c->forward('TestApp::View::Dump');
 }
index 53d79e2..5b29201 100644 (file)
@@ -1,5 +1,6 @@
 package TestApp::Controller::Root;
-
+use strict;
+use warnings;
 use base 'Catalyst::Controller';
 
 __PACKAGE__->config->{namespace} = '';
@@ -20,4 +21,36 @@ sub localregex : LocalRegex('^localregex$') {
     $c->forward('TestApp::View::Dump::Request');
 }
 
+sub index : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body('root index');
+}
+
+sub global_action : Private {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+sub class_forward_test_method :Private {
+    my ( $self, $c ) = @_;
+    $c->response->headers->header( 'X-Class-Forward-Test-Method' => 1 );
+}
+
+sub loop_test : Local {
+    my ( $self, $c ) = @_;
+
+    for( 1..1001 ) {
+        $c->forward( 'class_forward_test_method' );
+    }
+}
+
+sub recursion_test : Local {
+    my ( $self, $c ) = @_;
+    $c->forward( 'recursion_test' );
+}
+
+sub end : Private {
+    my ($self,$c) = @_;
+}
+
 1;
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;
index 00855cd..524ed8b 100644 (file)
@@ -45,15 +45,5 @@ sub execute {
     return $c->SUPER::execute(@_);
 }
 
+1;
 
-
-sub auto : Private {
-    my ( $self, $c ) = @_;
-    ++$c->stash->{auto_count};
-    return 1;
-}
-
-sub default : Private {
-    my ( $self, $c ) = @_;
-    $c->res->body( sprintf 'default, auto=%d', $c->stash->{auto_count} );
-}
diff --git a/t/lib/TestAppDoubleAutoBug/Controller/Root.pm b/t/lib/TestAppDoubleAutoBug/Controller/Root.pm
new file mode 100644 (file)
index 0000000..2d0b1a6
--- /dev/null
@@ -0,0 +1,22 @@
+package TestAppDoubleAutoBug::Controller::Root;
+
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+sub auto : Private {
+    my ( $self, $c ) = @_;
+    ++$c->stash->{auto_count};
+    return 1;
+}
+
+sub default : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body( sprintf 'default, auto=%d', $c->stash->{auto_count} );
+}
+
+sub end : Private {
+    my ($self,$c) = @_;
+}
+
+1;
diff --git a/t/lib/TestAppEncoding.pm b/t/lib/TestAppEncoding.pm
new file mode 100644 (file)
index 0000000..53f50ff
--- /dev/null
@@ -0,0 +1,11 @@
+package TestAppEncoding;
+use strict;
+use warnings;
+use base qw/Catalyst/;
+use Catalyst;
+
+__PACKAGE__->config(name => __PACKAGE__);
+__PACKAGE__->setup;
+
+1;
+
diff --git a/t/lib/TestAppEncoding/Controller/Root.pm b/t/lib/TestAppEncoding/Controller/Root.pm
new file mode 100644 (file)
index 0000000..b5b3eeb
--- /dev/null
@@ -0,0 +1,27 @@
+package TestAppEncoding::Controller::Root;
+use strict;
+use warnings;
+use base 'Catalyst::Controller';
+use Test::More;
+
+__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>; });
+}
+
+sub binary_utf8 : Local {
+    my ($self, $c) = @_;
+    $c->forward('binary');
+    my $str = $c->res->body;
+    utf8::upgrade($str);
+    ok utf8::is_utf8($str), 'Body is variable width encoded string';
+    $c->res->body($str);
+}
+
+sub end : Private {
+    my ($self,$c) = @_;
+}
+
+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 3d3b11b..74a2f27 100644 (file)
@@ -2,13 +2,15 @@ use strict;
 use warnings;
 
 package TestAppPathBug;
-
+use strict;
+use warnings;
 use Catalyst;
 
 our $VERSION = '0.01';
 
 __PACKAGE__->config( name => 'TestAppPathBug', root => '/some/dir' );
 
+__PACKAGE__->log(TestAppPathBug::Log->new);
 __PACKAGE__->setup;
 
 sub foo : Path {
@@ -16,4 +18,11 @@ sub foo : Path {
     $c->res->body( 'This is the foo method.' );
 }
 
+package TestAppPathBug::Log;
+use strict;
+use warnings;
+use base qw/Catalyst::Log/;
+
+sub warn {}
+
 1;
index 36d8e16..3d0d552 100644 (file)
@@ -4,12 +4,7 @@ use Test::More;
 use Test::Exception;
 use Catalyst qw/+TestPluginWithConstructor/;
 use Moose;
-BEGIN { extends qw/Catalyst Catalyst::Controller/ } # Ewww, FIXME.
-
-sub foo : Local {
-    my ($self, $c) = @_;
-    $c->res->body('foo');
-}
+extends qw/Catalyst/;
 
 __PACKAGE__->setup;
 our $MODIFIER_FIRED = 0;
diff --git a/t/lib/TestAppPluginWithConstructor/Controller/Root.pm b/t/lib/TestAppPluginWithConstructor/Controller/Root.pm
new file mode 100644 (file)
index 0000000..d032fd2
--- /dev/null
@@ -0,0 +1,12 @@
+package TestAppPluginWithConstructor::Controller::Root;
+
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+sub foo : Local {
+    my ($self, $c) = @_;
+    $c->res->body('foo');
+}
+
+1;
index bfc1340..84cc85c 100644 (file)
@@ -16,16 +16,11 @@ __PACKAGE__->log(TestAppStats::Log->new);
 
 __PACKAGE__->setup;
 
-# Return log messages from previous request
-sub default : Private {
-    my ( $self, $c ) = @_;
-    $c->stats->profile("test");
-    $c->res->body(join("\n", @log_messages));
-    @log_messages = ();
-}
-
 package TestAppStats::Log;
 use base qw/Catalyst::Log/;
 
-sub info { push(@log_messages, @_); }
-sub debug { push(@log_messages, @_); }
+sub info { push(@TestAppStats::log_messages, @_); }
+sub debug { push(@TestAppStats::log_messages, @_); }
+
+1;
+
diff --git a/t/lib/TestAppStats/Controller/Root.pm b/t/lib/TestAppStats/Controller/Root.pm
new file mode 100644 (file)
index 0000000..a46856a
--- /dev/null
@@ -0,0 +1,16 @@
+package TestAppStats::Controller::Root;
+use strict;
+use warnings;
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+# Return log messages from previous request
+sub default : Private {
+    my ( $self, $c ) = @_;
+    $c->stats->profile("test");
+    $c->res->body(join("\n", @TestAppStats::log_messages));
+    @TestAppStats::log_messages = ();
+}
+
+1;
diff --git a/t/lib/TestAppToTestScripts.pm b/t/lib/TestAppToTestScripts.pm
new file mode 100644 (file)
index 0000000..f32154a
--- /dev/null
@@ -0,0 +1,14 @@
+package TestAppToTestScripts;
+use strict;
+use warnings;
+use Carp;
+
+our @RUN_ARGS;
+
+sub run {
+    @RUN_ARGS = @_;
+    1; # Does this work?
+}
+
+1;
+
index e5bdb1c..e251568 100644 (file)
@@ -1,11 +1,17 @@
 # See t/plugin_new_method_backcompat.t
-package TestPluginWithConstructor;
+package Class::Accessor::Fast;
 use strict;
 use warnings;
+
 sub new {
     my $class = shift;
     return bless $_[0], $class;
 }
 
+package TestPluginWithConstructor;
+use strict;
+use warnings;
+use base qw/Class::Accessor::Fast/;
+
 1;
 
index 172f91e..34318ea 100644 (file)
@@ -3,8 +3,8 @@ use warnings;
 use Test::More;
 
 BEGIN {
-    unless (eval 'use CatalystX::LeakChecker 0.03; 1') {
-        plan skip_all => 'CatalystX::LeakChecker 0.03 required for this test';
+    unless (eval 'use CatalystX::LeakChecker 0.05; 1') {
+        plan skip_all => 'CatalystX::LeakChecker 0.05 required for this test';
     }
 
     plan tests => 4;
index d10e9d5..1fefc2a 100644 (file)
@@ -26,7 +26,6 @@ plan skip_all => 'Skipping fork tests: no /bin/ls'
 plan tests => 13; # otherwise
 
 {
-  system:
     ok(my $result = get('/fork/system/%2Fbin%2Fls'), 'system');
     my @result = split /$/m, $result;
     $result = join q{}, @result[-4..-1];
@@ -37,7 +36,6 @@ plan tests => 13; # otherwise
 }
 
 {
-  backticks:
     ok(my $result = get('/fork/backticks/%2Fbin%2Fls'), '`backticks`');
     my @result = split /$/m, $result;
     $result = join q{}, @result[-4..-1];
@@ -49,7 +47,6 @@ plan tests => 13; # otherwise
     like($result_ref->{result}, qr{\n.*\n}m, 'contains two newlines');
 }
 {
-  fork:
     ok(my $result = get('/fork/fork'), 'fork');
     my @result = split /$/m, $result;
     $result = join q{}, @result[-4..-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_core_mvc.t b/t/unit_core_mvc.t
deleted file mode 100644 (file)
index 8cb1fcb..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-use Test::More tests => 46;
-use strict;
-use warnings;
-
-use_ok('Catalyst');
-
-my @complist =
-  map { "MyApp::$_"; }
-  qw/C::Controller M::Model V::View Controller::C Model::M View::V Controller::Model::Dummy::Model Model::Dummy::Model/;
-
-{
-
-    package MyApp;
-
-    use base qw/Catalyst/;
-
-    __PACKAGE__->components( { map { ( ref($_)||$_ , $_ ) } @complist } );
-
-    my $thingie={};
-    bless $thingie, 'Some::Test::Object';
-    __PACKAGE__->components->{'MyApp::Model::Test::Object'} = $thingie;
-
-    # allow $c->log->warn to work
-    __PACKAGE__->setup_log;
-}
-
-is( MyApp->view('View'), 'MyApp::V::View', 'V::View ok' );
-
-is( MyApp->controller('Controller'),
-    'MyApp::C::Controller', 'C::Controller ok' );
-
-is( MyApp->model('Model'), 'MyApp::M::Model', 'M::Model ok' );
-
-is( MyApp->model('Dummy::Model'), 'MyApp::Model::Dummy::Model', 'Model::Dummy::Model ok' );
-
-isa_ok( MyApp->model('Test::Object'), 'Some::Test::Object', 'Test::Object ok' );
-
-is( MyApp->controller('Model::Dummy::Model'), 'MyApp::Controller::Model::Dummy::Model', 'Controller::Model::Dummy::Model ok' );
-
-is( MyApp->view('V'), 'MyApp::View::V', 'View::V ok' );
-
-is( MyApp->controller('C'), 'MyApp::Controller::C', 'Controller::C ok' );
-
-is( MyApp->model('M'), 'MyApp::Model::M', 'Model::M ok' );
-
-# failed search
-{
-    is( MyApp->model('DNE'), undef, 'undef for invalid search' );
-}
-
-is_deeply( [ sort MyApp->views ],
-           [ qw/V View/ ],
-           'views ok' );
-
-is_deeply( [ sort MyApp->controllers ],
-           [ qw/C Controller Model::Dummy::Model/ ],
-           'controllers ok');
-
-is_deeply( [ sort MyApp->models ],
-           [ qw/Dummy::Model M Model Test::Object/ ],
-           'models ok');
-
-{
-    my $warnings = 0;
-    no warnings 'redefine';
-    local *Catalyst::Log::warn = sub { $warnings++ };
-
-    like (MyApp->view , qr/^MyApp\::(V|View)\::/ , 'view() with no defaults returns *something*');
-    ok( $warnings, 'view() w/o a default is random, warnings thrown' );
-}
-
-is ( bless ({stash=>{current_view=>'V'}}, 'MyApp')->view , 'MyApp::View::V', 'current_view ok');
-
-my $view = bless {} , 'MyApp::View::V'; 
-is ( bless ({stash=>{current_view_instance=> $view }}, 'MyApp')->view , $view, 'current_view_instance ok');
-
-is ( bless ({stash=>{current_view_instance=> $view, current_view=>'MyApp::V::View' }}, 'MyApp')->view , $view, 
-  'current_view_instance precedes current_view ok');
-
-{
-    my $warnings = 0;
-    no warnings 'redefine';
-    local *Catalyst::Log::warn = sub { $warnings++ };
-
-    ok( my $model = MyApp->model );
-
-    ok( (($model =~ /^MyApp\::(M|Model)\::/) ||
-        $model->isa('Some::Test::Object')),
-        'model() with no defaults returns *something*' );
-
-    ok( $warnings, 'model() w/o a default is random, warnings thrown' );
-}
-
-is ( bless ({stash=>{current_model=>'M'}}, 'MyApp')->model , 'MyApp::Model::M', 'current_model ok');
-
-my $model = bless {} , 'MyApp::Model::M'; 
-is ( bless ({stash=>{current_model_instance=> $model }}, 'MyApp')->model , $model, 'current_model_instance ok');
-
-is ( bless ({stash=>{current_model_instance=> $model, current_model=>'MyApp::M::Model' }}, 'MyApp')->model , $model, 
-  'current_model_instance precedes current_model ok');
-
-MyApp->config->{default_view} = 'V';
-is ( bless ({stash=>{}}, 'MyApp')->view , 'MyApp::View::V', 'default_view ok');
-is ( MyApp->view , 'MyApp::View::V', 'default_view in class method ok');
-
-MyApp->config->{default_model} = 'M';
-is ( bless ({stash=>{}}, 'MyApp')->model , 'MyApp::Model::M', 'default_model ok');
-is ( MyApp->model , 'MyApp::Model::M', 'default_model in class method ok');
-
-# regexp behavior tests
-{
-    # is_deeply is used because regexp behavior means list context
-    is_deeply( [ MyApp->view( qr{^V[ie]+w$} ) ], [ 'MyApp::V::View' ], 'regexp view ok' );
-    is_deeply( [ MyApp->controller( qr{Dummy\::Model$} ) ], [ 'MyApp::Controller::Model::Dummy::Model' ], 'regexp controller ok' );
-    is_deeply( [ MyApp->model( qr{Dum{2}y} ) ], [ 'MyApp::Model::Dummy::Model' ], 'regexp model ok' );
-    
-    # object w/ qr{}
-    is_deeply( [ MyApp->model( qr{Test} ) ], [ MyApp->components->{'MyApp::Model::Test::Object'} ], 'Object returned' );
-
-    {
-        my $warnings = 0;
-        no warnings 'redefine';
-        local *Catalyst::Log::warn = sub { $warnings++ };
-
-        # object w/ regexp fallback
-        is_deeply( [ MyApp->model( 'Test' ) ], [ MyApp->components->{'MyApp::Model::Test::Object'} ], 'Object returned' );
-        ok( $warnings, 'regexp fallback warnings' );
-    }
-
-    is_deeply( [ MyApp->view('MyApp::V::View$') ], [ 'MyApp::V::View' ], 'Explicit return ok');
-    is_deeply( [ MyApp->controller('MyApp::C::Controller$') ], [ 'MyApp::C::Controller' ], 'Explicit return ok');
-    is_deeply( [ MyApp->model('MyApp::M::Model$') ], [ 'MyApp::M::Model' ], 'Explicit return ok');
-}
-
-{
-    my @expected = qw( MyApp::C::Controller MyApp::Controller::C );
-    is_deeply( [ sort MyApp->controller( qr{^C} ) ], \@expected, 'multiple controller returns from regexp search' );
-}
-
-{
-    my @expected = qw( MyApp::V::View MyApp::View::V );
-    is_deeply( [ sort MyApp->view( qr{^V} ) ], \@expected, 'multiple view returns from regexp search' );
-}
-
-{
-    my @expected = qw( MyApp::M::Model MyApp::Model::M );
-    is_deeply( [ sort MyApp->model( qr{^M} ) ], \@expected, 'multiple model returns from regexp search' );
-}
-
-# failed search
-{
-    is( scalar MyApp->controller( qr{DNE} ), 0, '0 results for failed search' );
-}
-
-#checking @args passed to ACCEPT_CONTEXT
-{
-    my $args;
-
-    {
-        no warnings 'once';
-        *MyApp::Model::M::ACCEPT_CONTEXT = sub { my ($self, $c, @args) = @_; $args= \@args};
-        *MyApp::View::V::ACCEPT_CONTEXT = sub { my ($self, $c, @args) = @_; $args= \@args};
-    }
-
-    my $c = bless {}, 'MyApp';
-
-    # test accept-context with class rather than instance
-    MyApp->model('M', qw/foo bar/);
-    is_deeply($args, [qw/foo bar/], 'MyApp->model args passed to ACCEPT_CONTEXT ok');
-
-
-    $c->model('M', qw/foo bar/);
-    is_deeply($args, [qw/foo bar/], '$c->model args passed to ACCEPT_CONTEXT ok');
-
-    my $x = $c->view('V', qw/foo2 bar2/);
-    is_deeply($args, [qw/foo2 bar2/], '$c->view args passed to ACCEPT_CONTEXT ok');
-
-    # regexp fallback
-    $c->view('::View::V', qw/foo3 bar3/);
-    is_deeply($args, [qw/foo3 bar3/], 'args passed to ACCEPT_CONTEXT ok');
-
-
-}
diff --git a/t/unit_dispatcher_requestargs_restore.t b/t/unit_dispatcher_requestargs_restore.t
deleted file mode 100644 (file)
index 731c4da..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-# Insane test case for the behavior needed by Plugin::Auhorization::ACL
-
-# We have to localise $c->request->{arguments} in 
-# Catalyst::Dispatcher::_do_forward, rather than using save and restore,
-# as otherwise, the calling $c->detach on an action which says
-# die $Catalyst:DETACH causes the request arguments to not get restored,
-# and therefore sub gorch gets the wrong string $frozjob parameter.
-
-# Please feel free to break this behavior once a sane hook for safely
-# executing another action from the dispatcher (i.e. wrapping actions)
-# is present, so that the Authorization::ACL plugin can be re-written
-# to not be full of such crazy shit.
-{
-    package ACLTestApp;
-    use Test::More;
-
-    use strict;
-    use warnings;
-    use MRO::Compat;
-    use Scalar::Util ();
-
-    use base qw/Catalyst Catalyst::Controller/;
-    use Catalyst qw//;
-
-    sub execute {
-        my $c = shift;
-        my ( $class, $action ) = @_;
-
-        if ( Scalar::Util::blessed($action)
-            and $action->name ne "foobar" ) {
-              eval { $c->detach( 'foobar', [$action, 'foo'] ) };
-        }
-
-        $c->next::method( @_ );
-    }
-
-    sub foobar : Private {
-        die $Catalyst::DETACH;
-    }
-
-    sub gorch : Local {
-        my ( $self, $c, $frozjob ) = @_;
-        is $frozjob, 'wozzle';
-        $c->res->body("gorch");
-    }
-
-    __PACKAGE__->setup;
-}
-
-use strict;
-use warnings;
-use FindBin qw/$Bin/;
-use lib "$Bin/lib";
-use Catalyst::Test 'ACLTestApp';
-use Test::More tests => 1;
-
-request('http://localhost/gorch/wozzle');
diff --git a/t/unit_metaclass_compat_non_moose_controller.t b/t/unit_metaclass_compat_non_moose_controller.t
deleted file mode 100644 (file)
index cb3c1e2..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-use Catalyst ();
-
-{
-    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 Test::More tests => 1;
-use Test::Exception;
-
-# Metaclass init order causes fail.
-# There are TODO tests in Moose for this, see
-# f2391d17574eff81d911b97be15ea51080500003
-# after which the evil kludge in core can die in a fire.
-
-lives_ok {
-    TestApp::Controller::Base->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;