my %final_attributes;
- foreach my $key (keys %raw_attributes) {
+ while (my ($key, $value) = each %raw_attributes){
+ my $new_attrs = $self->_parse_attr($c, $name, $key => $value );
+ push @{ $final_attributes{$_} }, @{ $new_attrs->{$_} } for keys %$new_attrs;
+ }
- my $raw = $raw_attributes{$key};
+ return \%final_attributes;
+}
- foreach my $value (ref($raw) eq 'ARRAY' ? @$raw : $raw) {
+sub _parse_attr {
+ my ($self, $c, $name, $key, $values) = @_;
- my $meth = "_parse_${key}_attr";
- if ( my $code = $self->can($meth) ) {
- ( $key, $value ) = $self->$code( $c, $name, $value );
+ my %final_attributes;
+ foreach my $value (ref($values) eq 'ARRAY' ? @$values : $values) {
+ my $meth = "_parse_${key}_attr";
+ if ( my $code = $self->can($meth) ) {
+ my %new_attrs = $self->$code( $c, $name, $value );
+ while (my ($new_key, $value) = each %new_attrs){
+ my $new_attrs = $key eq $new_key ?
+ { $new_key => [$value] } :
+ $self->_parse_attr($c, $name, $new_key => $value );
+ push @{ $final_attributes{$_} }, @{ $new_attrs->{$_} } for keys %$new_attrs;
}
+ }
+ else {
push( @{ $final_attributes{$key} }, $value );
}
}
sub _parse_Global_attr {
my ( $self, $c, $name, $value ) = @_;
- return $self->_parse_Path_attr( $c, $name, "/$name" );
+ # _parse_attr will call _parse_Path_attr for us
+ return Path => "/$name";
}
sub _parse_Absolute_attr { shift->_parse_Global_attr(@_); }
sub _parse_Local_attr {
my ( $self, $c, $name, $value ) = @_;
- return $self->_parse_Path_attr( $c, $name, $name );
+ # _parse_attr will call _parse_Path_attr for us
+ return Path => $name;
}
sub _parse_Relative_attr { shift->_parse_Local_attr(@_); }
my ( $self, $c, $name, $value ) = @_;
my $appclass = Catalyst::Utils::class2appclass($self);
- $value = "${appclass}::Action::${value}";
+ $value = "+${appclass}::Action::${value}";
return ( 'ActionClass', $value );
}
use strict;
use warnings;
+use Data::Dumper;
+$Data::Dumper::Maxdepth=1;
use FindBin;
use lib "$FindBin::Bin/../lib";
-use Test::More tests => 4;
+use Test::More tests => 13;
use Catalyst::Test 'TestApp';
+sub ok_actions {
+ my ($response, $actions, $msg) = @_;
+ my $expected = join ", ",
+ (map { "TestApp::Controller::Attributes->$_" } @$actions),
+ 'TestApp::Controller::Root->end';
+ is( $response->header('x-catalyst-executed') => $expected,
+ $msg//'Executed correct acitons');
+ }
+
ok( my $response = request('http://localhost/attributes/view'),
'get /attributes/view' );
ok( !$response->is_success, 'Response Unsuccessful' );
ok( $response = request('http://localhost/attributes/foo'),
"get /attributes/foo" );
+ok_actions($response => ['foo']);
+
+ok( $response = request('http://localhost/attributes/all_attrs'),
+ "get /attributes/all_attrs" );
+ok( $response->is_success, "Response OK" );
+ok_actions($response => [qw/fetch all_attrs_action/]);
+ok( $response = request('http://localhost/attributes/some_attrs'),
+ "get /attributes/some_attrs" );
ok( $response->is_success, "Response OK" );
+ok_actions($response => [qw/fetch some_attrs_action/]);
+
+ok( $response = request('http://localhost/attributes/one_attr'),
+ "get /attributes/one_attr" );
+ok( $response->is_success, "Response OK" );
+ok_actions($response => [qw/fetch one_attr_action/]);
+
+
package My::AttributesBaseClass;
use base qw( Catalyst::Controller );
-sub fetch : Chained('/') PathPrefix CaptureArgs(1) {
+sub fetch : Chained('/') PathPrefix CaptureArgs(0) { }
-}
+sub left_alone :Chained('fetch') PathPart Args(0) { }
-sub view : PathPart Chained('fetch') Args(0) {
+sub view : PathPart Chained('fetch') Args(0) { }
-}
+sub foo { } # no attributes
-sub foo { # no attributes
+package TestApp::Controller::Attributes;
+use base qw(My::AttributesBaseClass);
+sub _parse_MakeMeVisible_attr {
+ my ($self, $c, $name, $value) = @_;
+ if (!$value){
+ return Chained => 'fetch', PathPart => 'all_attrs', Args => 0;
+ }
+ elsif ($value eq 'some'){
+ return Chained => 'fetch', Args => 0;
+ }
+ elsif ($value eq 'one'){
+ return PathPart => 'one_attr';
+ }
}
-package TestApp::Controller::Attributes;
-use base qw(My::AttributesBaseClass);
+sub view { } # override attributes to "hide" url
-sub view { # override attributes to "hide" url
+sub foo : Local { }
-}
+sub all_attrs_action :MakeMeVisible { }
-sub foo : Local {
+sub some_attrs_action :MakeMeVisible('some') PathPart('some_attrs') { }
-}
+sub one_attr_action :MakeMeVisible('one') Chained('fetch') Args(0) { }
1;