inject_component can now compose roles
John Napiorkowski [Tue, 14 Apr 2015 21:26:27 +0000 (16:26 -0500)]
Changes
lib/Catalyst/Utils.pm
t/Test/Apple.pm [deleted file]
t/inject_component_util.t

diff --git a/Changes b/Changes
index a93c67b..7da6712 100644 (file)
--- 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
index babcfa3..db89063 100644 (file)
@@ -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 L<Moose::Role>s 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<NOTE:> This is basically a core version of L<CatalystX::InjectComponent>.  If
 you can now use this safely instead.  Going forward changes required to make this work will be
 synchronized with the core method.
 
+B<NOTE:> The 'traits' option is unique to the L<Catalyst::Utils> version of this feature.
+
+B<NOTE:> These injected components really need to be a L<Catalyst::Component> and a L<Moose>
+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 (file)
index c6f354e..0000000
+++ /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;
index 7162202..5b9c2d0 100644 (file)
@@ -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;