From: John Napiorkowski Date: Thu, 26 Mar 2015 19:36:55 +0000 (-0500) Subject: first pass at constraints on uri_for X-Git-Tag: 5.90089_002~21 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=commitdiff_plain;h=86a399db181f9d13bc7fbb2911639d478ce1b782;hp=c1192f1ed63f124eb2d143e10b215703e7dc6284 first pass at constraints on uri_for --- diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index f013027..576f0c4 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -1491,18 +1491,18 @@ sub uri_for { : ()) ]; my $action = $path; + my $expanded_action = $c->dispatcher->expand_action( $action ); + my $num_captures = $expanded_action->number_of_captures; + # ->uri_for( $action, \@captures_and_args, \%query_values? ) if( !@encoded_args && $action->number_of_args ) { - my $expanded_action = $c->dispatcher->expand_action( $action ); - my $num_captures = $expanded_action->number_of_captures; - unshift @encoded_args, splice @$captures, $num_captures; + unshift @encoded_args, splice @$captures, $num_captures; } - # use Devel::Dwarn;Dwarn $captures; - - if($action->has_captures_constraints) { - unless($action->match_captures($c, $captures)) { - carp "@{$captures} do not match the type constraints in $action"; + if($num_captures) { + unless($expanded_action->match_captures($c, $captures)) { + carp "captures [@{$captures}] do not match the type constraints in action '$action'"; + return; } } @@ -1515,9 +1515,10 @@ sub uri_for { $path = '/' if $path eq ''; # At this point @encoded_args is the remaining Args (all captures removed). - if($action->has_args_constraints) { - unless($action->match_args($c,\@encoded_args)) { - carp "@encoded_args do not match the type constraints in $action"; + if($expanded_action->has_args_constraints) { + unless($expanded_action->match_args($c,\@encoded_args)) { + carp "args [@encoded_args] do not match the type constraints in action '$expanded_action'"; + return; } } } @@ -1582,8 +1583,8 @@ sub uri_for { } @keys); } - warn $base; - warn $args; + #warn $base; + #warn $args; my $res = bless(\"${base}${args}${query}", $class); $res; diff --git a/lib/Catalyst/ActionChain.pm b/lib/Catalyst/ActionChain.pm index 5e222c2..873e3a8 100644 --- a/lib/Catalyst/ActionChain.pm +++ b/lib/Catalyst/ActionChain.pm @@ -61,6 +61,17 @@ sub number_of_captures { return $captures; } +sub match_captures { + my ($self, $c, $captures) = @_; + my @captures = @{$captures||[]}; + + foreach my $link(@{$self->chain}) { + my @local_captures = splice @captures,0,$link->number_of_captures; + return unless $link->match_captures($c, \@local_captures); + } + return 1; +} + # the scheme defined at the end of the chain is the one we use # but warn if too many. @@ -103,6 +114,10 @@ Catalyst::ActionChain object representing a chain of these actions Returns the total number of captures for the entire chain of actions. +=head2 match_captures + +Match all the captures that this chain encloses, if any. + =head2 scheme Any defined scheme for the actionchain diff --git a/t/arg_constraints.t b/t/arg_constraints.t index 80b53f6..e948dee 100644 --- a/t/arg_constraints.t +++ b/t/arg_constraints.t @@ -367,22 +367,54 @@ SKIP: { { # URI testing my ($res, $c) = ctx_request '/'; - ok my $url1 = $c->uri_for($c->controller('Root')->action_for('finally'), [1,2,3,4,5],6); - warn $url1; - ok my $url2 = $c->uri_for($c->controller('Root')->action_for('finally'), [1,2,3,4,5,6]); - warn $url2; + { + ok my $url = eval { $c->uri_for($c->controller('Root')->action_for('user'), 2) }; + is $url, 'http://localhost/user/2'; + } - ok my $url3 = $c->uri_for($c->controller('Root')->action_for('user'), 2); - warn $url3; + { + ok my $url = eval { $c->uri_for($c->controller('Root')->action_for('user'), [2]) }; + is $url, 'http://localhost/user/2'; + } - ok my $url4 = $c->uri_for($c->controller('Root')->action_for('user'), [2]); - warn $url4; + { + ok my $url = ! eval { $c->uri_for($c->controller('Root')->action_for('user'), [20]) }; + } + + { + ok my $url = eval { $c->uri_for($c->controller('Root')->action_for('finally'), [1,2,3,4,4],6) }; + is $url, 'http://localhost/chain_base/1/2/3/4/4/6'; + } + + { + ok my $url = eval { $c->uri_for($c->controller('Root')->action_for('finally'), [1,2,3,4,4,6]) }; + is $url, 'http://localhost/chain_base/1/2/3/4/4/6'; + } + + { + ok my $url = ! eval { $c->uri_for($c->controller('Root')->action_for('finally'), [1,2,3,4,5,6]) }; + } + + { + ok my $url = eval { $c->uri_for($c->controller('Root')->action_for('finally'), ['a',2,3,4,4,6]) }; + is $url, 'http://localhost/chain_base/a/2/3/4/4/6'; + } + + { + ok my $url = ! eval { $c->uri_for($c->controller('Root')->action_for('finally'), ['a','1',3,4,4,'a']) }; + } + + { + ok my $url = ! eval { $c->uri_for($c->controller('Root')->action_for('finally'), ['a','a',3,4,4,'6']) }; + } } done_testing; + __END__ +