From: John Napiorkowski Date: Thu, 21 Jul 2022 20:01:45 +0000 (-0500) Subject: change forward/detach to work with instances X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=978a9a4ac27fc9cc84ada858ace22cd223e20fc2;p=catagits%2FCatalyst-Runtime.git change forward/detach to work with instances Right now if you $c->forward($view) where $view is an instance of a view the code will create a new view object of the same type and forward to that, rather than forward to the view instance (and other components). This fixes that --- diff --git a/lib/Catalyst/Dispatcher.pm b/lib/Catalyst/Dispatcher.pm index 9ac3581..7a31c77 100644 --- a/lib/Catalyst/Dispatcher.pm +++ b/lib/Catalyst/Dispatcher.pm @@ -328,37 +328,39 @@ sub _find_component { } sub _invoke_as_component { - my ( $self, $c, $component_or_class, $method ) = @_; - - my $component = $self->_find_component($c, $component_or_class); - my $component_class = blessed $component || return 0; - - if (my $code = $component_class->can('action_for')) { - my $possible_action = $component->$code($method); - return $possible_action if $possible_action; - } - - if ( my $code = $component_class->can($method) ) { - return $self->_method_action_class->new( - { - name => $method, - code => $code, - reverse => "$component_class->$method", - class => $component_class, - namespace => Catalyst::Utils::class2prefix( - $component_class, ref($c)->config->{case_sensitive} - ), - } - ); - } - else { - my $error = - qq/Couldn't forward to "$component_class". Does not implement "$method"/; - $c->error($error); - $c->log->debug($error) - if $c->debug; - return 0; - } + my ( $self, $c, $component_or_class, $method ) = @_; + + my $component = $self->_find_component($c, $component_or_class); + my $component_class = blessed $component || return 0; + + if (my $code = $component_class->can('action_for')) { + my $possible_action = $component->$code($method); + return $possible_action if $possible_action; + } + + my $component_to_call = blessed($component_or_class) ? $component_or_class : $component_class; + + if ( my $code = $component_to_call->can($method) ) { + return $self->_method_action_class->new( + { + name => $method, + code => $code, + reverse => "$component_class->$method", + class => $component_to_call, + namespace => Catalyst::Utils::class2prefix( + $component_class, ref($c)->config->{case_sensitive} + ), + } + ); + } + else { + my $error = + qq/Couldn't forward to "$component_class". Does not implement "$method"/; + $c->error($error); + $c->log->debug($error) + if $c->debug; + return 0; + } } =head2 $self->prepare_action($c) diff --git a/t/forward_instances.t b/t/forward_instances.t new file mode 100644 index 0000000..3588d91 --- /dev/null +++ b/t/forward_instances.t @@ -0,0 +1,50 @@ +use warnings; +use strict; +use Test::More; + +# Test case for reported issue when an action consumes JSON but a +# POST sends nothing we get a hard error + +{ + package MyApp::Controller::Root; + $INC{'MyApp/Controller/Root.pm'} = __FILE__; + + use base 'Catalyst::Controller'; + + sub test :Local Args(0) { + my( $self, $c ) = @_; + my $view = $c->view('Test'); + $c->forward($view); + + Test::More::is("$view", "@{[ $c->res->body]}"); + } + + package MyApp::View::Test; + $INC{'MyApp/View/Test.pm'} = __FILE__; + + use base 'Catalyst::View'; + + sub ACCEPT_CONTEXT { + my ($self, $c, @args) = @_; + return ref($self)->new; + } + + sub process { + my ($self, $c, @args) = @_; + $c->res->body("$self"); + + } + + package MyApp; + use Catalyst; + MyApp->setup; +} + +use HTTP::Request::Common; +use Catalyst::Test 'MyApp'; + +{ + ok my $res = request GET 'root/test'; +} + +done_testing(2);