File Coverage

blib/lib/Catalyst/ActionRole/QueryMatching.pm
Criterion Covered Total %
statement 33 36 91.6
branch 15 20 75.0
condition 1 4 25.0
subroutine 7 7 100.0
pod n/a
total 56 67 83.5


line stmt bran cond sub pod time code
1              
2             use Moose::Role;
3 2     2   1420 use Moose::Util::TypeConstraints ();
  2         4  
  2         19  
4 2     2   8900  
  2         5  
  2         1290  
5             requires 'match', 'match_captures', 'list_extra_info';
6              
7              
8 15 50   15   20 has is_slurpy => (
  15         326  
9             is=>'ro',
10             init_arg=>undef,
11             isa=>'Bool',
12             required=>1,
13             lazy=>1,
14             builder=>'_build_is_slurpy');
15              
16             my $self = shift;
17             my($query, @extra) = $self->_query_attr;
18             return $query =~m/^.+,\.\.\.$/ ? 1:0;
19 7     7   11 }
20 7         12  
21 7 100       199 has query_constraints => (
22             is=>'ro',
23             init_arg=>undef,
24             isa=>'ArrayRef|Ref',
25             required=>1,
26             lazy=>1,
27             builder=>'_build_query_constraints');
28              
29             my $self = shift;
30             my ($constraint_proto, @extra) = $self->_query_attr;
31              
32             die "Action ${\$self->private_path} defines more than one 'Query' attribute" if scalar @extra;
33 8     8   14 return +{} unless defined($constraint_proto);
34 8         29  
35             $constraint_proto =~s/^(.+),\.\.\.$/$1/; # slurpy is handled elsewhere
36 8 50       20  
  0         0  
37 8 50       22 # Query may be a Hash like Query(p=>Int,q=>Str) OR it may be a Ref like
38             # Query(Tuple[p=>Int, slurpy HashRef]). The only way to figure is to eval it
39 8         32 # and look at what we have.
40             my @signature = eval "package ${\$self->class}; $constraint_proto"
41             or die "'$constraint_proto' is not valid Query Contraint at action ${\$self->private_path}, error '$@'";
42              
43             if(scalar(@signature) > 1) {
44 8 50       12 # Do a dance to support old school stringy types
  8         171  
45 0         0 # At this point we 'should' have a hash...
46             my %pairs = @signature;
47 8 100       23178 foreach my $key(keys %pairs) {
48             next if ref $pairs{$key};
49             $pairs{$key} = Moose::Util::TypeConstraints::find_or_parse_type_constraint($pairs{$key}) ||
50 7         21 die "'$pairs{$key}' is not a valid type constraint in Action ${\$self->private_path}";
51 7         23 }
52 10 100       143 return \%pairs;
53 2   50     15 } else {
54             # We have a 'reference type' constraint, like Dict[p=>Int,...]
55             return $signature[0] if ref($signature[0]); # Is like Tiny::Type
56 7         307 return Moose::Util::TypeConstraints::find_or_parse_type_constraint($signature[0]) ||
57             die "'$signature[0]' is not a valid type constraint in Action ${\$self->private_path}";
58             }
59 1 50       40 }
60 0   0     0  
61             around ['match','match_captures'] => sub {
62             my ($orig, $self, $c, @args) = @_;
63             my $tc = $self->query_constraints;
64             if(ref $tc eq 'HASH') {
65             # Do the key names match, unless slurpy?
66             unless($self->is_slurpy) {
67             return 0 unless $self->_compare_arrays([sort keys %$tc],[sort keys %{$c->req->query_parameters}]);
68             }
69             for my $key(keys %$tc) {
70             $tc->{$key}->check($c->req->query_parameters->{$key}) || return 0;
71             }
72             } else {
73             $tc->check($c->req->query_parameters) || return 0;
74             }
75              
76             return $self->$orig($c, @args);
77             };
78              
79             around 'list_extra_info' => sub {
80             my ($orig, $self, @args) = @_;
81             return {
82             %{ $self->$orig(@args) },
83             };
84             };
85              
86             my ($self, $first, $second) = @_;
87             no warnings; # silence spurious -w undef complaints
88             return 0 unless @$first == @$second;
89             for (my $i = 0; $i < @$first; $i++) {
90             return 0 if $first->[$i] ne $second->[$i];
91 9     9   18 }
92 2     2   26 return 1;
  2         5  
  2         243  
93 9 100       36 }
94 8         31  
95 15 100       49 1;
96              
97 7         16 =head1 NAME
98              
99             Catalyst::ActionRole::QueryMatching - Match on GET parameters using type constraints
100              
101             =head1 SYNOPSIS
102              
103             TBD
104              
105             =head1 DESCRIPTION
106              
107             TBD
108              
109             =head1 METHODS
110              
111             This role defines the following methods
112              
113             =head2 TBD
114              
115             TBD
116              
117             =head1 AUTHORS
118              
119             Catalyst Contributors, see Catalyst.pm
120              
121             =head1 COPYRIGHT
122              
123             This library is free software. You can redistribute it and/or modify it under
124             the same terms as Perl itself.
125              
126             =cut