Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions lib/Catalyst/Controller.pm
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,22 @@ sub _parse_attrs {
my %raw_attributes;

foreach my $attr (@attrs) {

# Parse out :Foo(bar) into Foo => bar etc (and arrayify)

if ( my ( $key, $value ) = ( $attr =~ /^(.*?)(?:\(\s*(.+?)?\s*\))?$/ ) )
if ( my ( $key, $value ) = $attr =~ m{
\A
(\S*?) # match the key e.g. Foo in example
(?:
\( \s*
(.+?)? # match attr content e.g. "bar" in example
\s* \)
)?
\z
}xms )
{

if ( defined $value ) {
( $value =~ s/^'(.*)'$/$1/ ) || ( $value =~ s/^"(.*)"/$1/ );
# Unquote single/double quoted attr values e.g. Foo("bar")
$value =~ s/^(['"])(.*)\1$/$2/s;
}
push( @{ $raw_attributes{$key} }, $value );
}
Expand Down
43 changes: 43 additions & 0 deletions t/aggregate/live_component_controller_action_action.t
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,50 @@ sub run_tests {
my $action = eval $response->content;
is_deeply $action->attributes->{extra_attribute}, [13];
is_deeply $action->attributes->{another_extra_attribute}, ['foo'];

# Test a multi-line attribute on the action comes through as expected
is_deeply $action->attributes->{MultiLineAttr}, ["one\n two\n three"];
# and a normal one e.g. `Foo('bar')`
is_deeply $action->attributes->{Foo}, ['bar'];
# and one without a value, e.g. `Baz` - note that the presence of
# the arrayref shows it was there
is_deeply $action->attributes->{Baz}, [undef];
}

{
ok( my $response = request('http://localhost/action_action_eightpointfive'),
'Request' );
ok( $response->is_success, 'Response Successful 2xx' );
is( $response->content_type, 'text/plain', 'Response Content-Type' );
is( $response->header('X-Catalyst-Action'),
'action_action_eightpointfive', 'Test Action' );
is(
$response->header('X-Test-Class'),
'TestApp::Controller::Action::Action',
'Test Class'
);
like(
$response->content,
qr/^bless\( .* 'Catalyst::Action' \)$/s,
'Content is a serialized Catalyst::Action'
);

require Catalyst::Action; # when running against a remote server, we
# need to load the class in the test process
# to be able to introspect the action instance
# later.
my $action = eval $response->content;
is_deeply $action->attributes->{extra_attribute}, [13];

# Test a multi-line attribute on the action comes through as expected
is_deeply $action->attributes->{MultiLineAttrQuoted}, ["\n 'one'\n 'two'\n 'three'\n"];
# and a normal one e.g. `Foo('bar')`
is_deeply $action->attributes->{Foo}, ['bar'];
# and one without a value, e.g. `Baz` - note that the presence of
# the arrayref shows it was there
is_deeply $action->attributes->{Baz}, [undef];
}

{
ok( my $response = request('http://localhost/action_action_nine'),
'Request' );
Expand Down
16 changes: 15 additions & 1 deletion t/lib/TestApp/Controller/Action/Action.pm
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,20 @@ sub action_action_seven : Global : ActionClass('~TestExtraArgsAction') {
$c->forward('TestApp::View::Dump::Request');
}

sub action_action_eight : Global {
sub action_action_eight : Global Foo('bar') MultiLineAttr(
one
two
three
) Baz {
my ( $self, $c ) = @_;
$c->forward('TestApp::View::Dump::Action');
}

sub action_action_eightpointfive : Global Foo('bar') MultiLineAttrQuoted("
'one'
'two'
'three'
") Baz {
my ( $self, $c ) = @_;
$c->forward('TestApp::View::Dump::Action');
}
Expand All @@ -62,4 +75,5 @@ sub action_action_nine : Global : ActionClass('~TestActionArgsFromConstructor')
my ( $self, $c ) = @_;
$c->forward('TestApp::View::Dump::Request');
}

1;