From: John Napiorkowski Date: Tue, 14 Apr 2015 21:26:27 +0000 (-0500) Subject: inject_component can now compose roles X-Git-Tag: 5.90089_002~9 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=commitdiff_plain;h=cbe627b901f8e459035a76d423229694e1fefbff inject_component can now compose roles --- diff --git a/Changes b/Changes index a93c67b..7da6712 100644 --- a/Changes +++ b/Changes @@ -17,7 +17,9 @@ - NEW FEATURE: New method in Catalyst::Utils 'inject_component', which is a core version of the previously external addon 'CatalystX::InjectComponent'. You should start to convert your existing code which uses the stand alone version, since - going forward only the core version will be supported. + going forward only the core version will be supported. Also the core version in + Catalyst::Utils has an additional feature to compose roles into the injected + component. - NEW FEATURE: Concepts from 'CatalystX::RoleApplicator' have been moved to core so we now have the follow application attributes 'request_class_traits', 'response_class_traits' and 'stats_class_traits' which allow you to compose diff --git a/lib/Catalyst/Utils.pm b/lib/Catalyst/Utils.pm index babcfa3..db89063 100644 --- a/lib/Catalyst/Utils.pm +++ b/lib/Catalyst/Utils.pm @@ -12,6 +12,7 @@ use String::RewritePrefix; use Class::Load (); use namespace::clean; use Devel::InnerPackage; +use Moose::Util; =head1 NAME @@ -509,6 +510,7 @@ Used to add components at runtime: into The Catalyst package to inject into (e.g. My::App) component The component package to inject + traits (Optional) ArrayRef of Ls that the componet should consume. as An optional moniker to use as the package name for the derived component For example: @@ -532,6 +534,11 @@ B This is basically a core version of L. If you can now use this safely instead. Going forward changes required to make this work will be synchronized with the core method. +B The 'traits' option is unique to the L version of this feature. + +B These injected components really need to be a L and a L +based class. + =cut sub inject_component { @@ -560,6 +567,7 @@ sub inject_component { unless ( Class::Load::is_class_loaded $component_package ) { eval "package $component_package; use base qw/$component/; 1;" or croak "Unable to build component package for \"$component_package\": $@"; + Moose::Util::apply_all_roles($component_package, @{$given{traits}}) if $given{traits}; (my $file = "$component_package.pm") =~ s{::}{/}g; $INC{$file} ||= 1; } diff --git a/t/Test/Apple.pm b/t/Test/Apple.pm deleted file mode 100644 index c6f354e..0000000 --- a/t/Test/Apple.pm +++ /dev/null @@ -1,14 +0,0 @@ -package t::Test::Apple; - -use strict; -use warnings; - -use parent qw/Catalyst::Controller/; - -sub default :Path { -} - -sub apple :Local { -} - -1; diff --git a/t/inject_component_util.t b/t/inject_component_util.t index 7162202..5b9c2d0 100644 --- a/t/inject_component_util.t +++ b/t/inject_component_util.t @@ -6,10 +6,29 @@ use FindBin; use lib "$FindBin::Bin/lib"; BEGIN { +package RoleTest1; + +use Moose::Role; + +sub aaa { 'aaa' } + +package RoleTest2; + +use Moose::Role; + +sub bbb { 'bbb' } + package Model::Banana; use base qw/Catalyst::Model/; + +package Model::BananaMoose; +use Moose; +extends 'Catalyst::Model'; + +Model::BananaMoose->meta->make_immutable; + package TestCatalyst; $INC{'TestCatalyst.pm'} = 1; use Catalyst::Runtime '5.70'; @@ -24,7 +43,9 @@ after 'setup_components' => sub { Catalyst::Utils::inject_component( into => __PACKAGE__, component => 'Model::Banana' ); Catalyst::Utils::inject_component( into => __PACKAGE__, component => 'Test::Apple' ); Catalyst::Utils::inject_component( into => __PACKAGE__, component => 'Model::Banana', as => 'Cherry' ); + Catalyst::Utils::inject_component( into => __PACKAGE__, component => 'Model::BananaMoose', as => 'CherryMoose', traits => ['RoleTest1', 'RoleTest2'] ); Catalyst::Utils::inject_component( into => __PACKAGE__, component => 'Test::Apple', as => 'Apple' ); + Catalyst::Utils::inject_component( into => __PACKAGE__, component => 'Test::Apple', as => 'Apple2', traits => ['RoleTest1', 'RoleTest2'] ); }; TestCatalyst->config( 'home' => '.' ); @@ -39,5 +60,9 @@ use Catalyst::Test qw/TestCatalyst/; ok( TestCatalyst->controller( $_ ) ) for qw/ Apple Test::Apple /; ok( TestCatalyst->model( $_ ) ) for qw/ Banana Cherry /; +is( TestCatalyst->controller('Apple2')->aaa, 'aaa'); +is( TestCatalyst->controller('Apple2')->bbb, 'bbb'); +is( TestCatalyst->model('CherryMoose')->aaa, 'aaa'); +is( TestCatalyst->model('CherryMoose')->bbb, 'bbb'); done_testing;