From: Alexander Hartmaier Date: Mon, 5 Oct 2009 11:57:34 +0000 (+0000) Subject: Improved the suggested fix warning when component resolution uses regex fallback... X-Git-Tag: 5.80014~37 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=commitdiff_plain;h=ab86b4807e99ae29a843e42cdc01f068c2cae734 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. --- diff --git a/Changes b/Changes index e07520c..44e1081 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,12 @@ 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. (abraxxa) + + New features: + - Added disable_component_resolution_regex_fallback config option to + switch off regex fallback for component resolution. (abraxxa) 5.80013 2009-09-17 11:07:04 diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index c4a39f8..44431f8 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -552,6 +552,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; @@ -569,7 +573,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 " . @@ -578,7 +583,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}/)"; } @@ -795,6 +800,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 { diff --git a/t/unit_core_mvc.t b/t/unit_core_mvc.t index 8cb1fcb..b5bbd8b 100644 --- a/t/unit_core_mvc.t +++ b/t/unit_core_mvc.t @@ -1,4 +1,4 @@ -use Test::More tests => 46; +use Test::More tests => 51; use strict; use warnings; @@ -181,3 +181,47 @@ is ( MyApp->model , 'MyApp::Model::M', 'default_model in class method ok'); } + +{ + my $warn = ''; + no warnings 'redefine'; + local *Catalyst::Log::warn = sub { $warn .= $_[1] }; + + is_deeply (MyApp->controller('MyApp::Controller::C'), + MyApp->components->{'MyApp::Controller::C'}, + 'controller by fully qualified name ok'); + + # You probably meant $c->controller('C') instead of $c->controller({'MyApp::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' ); +}