File Coverage

blib/lib/Data/Validator/MultiManager.pm
Criterion Covered Total %
statement 87 93 93.5
branch 8 16 50.0
condition 4 10 40.0
subroutine 22 24 91.6
pod 4 4 100.0
total 125 147 85.0


line stmt bran cond sub pod time code
1             package Data::Validator::MultiManager;
2 5     5   375861 use 5.008005;
  5         19  
  5         194  
3 5     5   27 use strict;
  5         10  
  5         166  
4 5     5   36 use warnings;
  5         9  
  5         163  
5              
6 5     5   22 use Carp qw(croak);
  5         8  
  5         288  
7 5     5   3837 use Clone qw(clone);
  5         92617  
  5         5880  
8              
9             our $VERSION = "0.01";
10              
11             sub new {
12 4     4 1 69 my ($class, $validator) = @_;
13              
14 4   100     35 $validator ||= 'Data::Validator';
15 4         22 _load_class($validator);
16              
17 4         50 bless {
18             validator_class => $validator,
19             priority => [],
20             validators => {},
21             common => {},
22             }, $class;
23             }
24              
25             sub add {
26 4     4 1 67 my ($self, @args) = @_;
27 4 50 33     60 croak 'must be specified key-value pair' unless @args && scalar @args % 2 == 0;
28              
29 4         31 while (my ($tag, $rule) = splice @args, 0, 2) {
30 8         21 my %merged_rule = (%{clone $self->{common}}, %$rule);
  8         165  
31 8         115 my $validator = $self->{validator_class}->new(%merged_rule);
32 8         10035 $validator->with('NoThrow', 'NoRestricted');
33              
34 8         50596 push @{$self->{priority}}, $tag;
  8         36  
35 8         101 $self->{validators}->{$tag} = $validator;
36             }
37             }
38              
39             sub common {
40 1     1 1 14 my ($self, %rule) = @_;
41 1         8 $self->{common} = \%rule;
42             }
43              
44             sub validate {
45 14     14 1 63583 my ($self, $param) = @_;
46 14         123 my $result = Data::Validator::MultiManager::Result->new($param, $self->{priority});
47              
48 14         25 for my $tag (@{$self->{priority}}) {
  14         42  
49 25         70 my $validator = $self->{validators}->{$tag};
50 25         111 my $args = $validator->validate($param);
51              
52 25 100       3635 if (my $errors = $validator->clear_errors) {
53 19         72 $result->set_errors($tag, $errors);
54             }
55             else {
56 6         34 $result->set_tag($tag);
57 6         21 $result->set_value($tag, $args);
58 6         70 return $result;
59             }
60             }
61 8         30 return $result;
62             }
63              
64             # copy from Plack::Util
65             sub _load_class {
66 4     4   10 my($class, $prefix) = @_;
67              
68 4 50       17 if ($prefix) {
69 0 0 0     0 unless ($class =~ s/^\+// || $class =~ /^$prefix/) {
70 0         0 $class = "$prefix\::$class";
71             }
72             }
73              
74 4         11 my $file = $class;
75 4         30 $file =~ s!::!/!g;
76 4         6154 require "$file.pm"; ## no critic
77              
78 4         111487 return $class;
79             }
80              
81             package
82             Data::Validator::MultiManager::Result;
83              
84             sub new {
85 14     14   31 my ($class, $original, $priority) = @_;
86              
87 14         117 my $self = bless {
88             priority => $priority,
89             errors => {},
90             tag => '',
91             values => {},
92             }, $class;
93 14         67 $self->set_original($original);
94 14         35 return $self;
95             }
96              
97             sub set_errors {
98 19     19   42 my ($self, $tag, $errors) = @_;
99 19         90 $self->{errors}->{$tag} = $errors;
100             }
101              
102             sub set_value {
103 6     6   9 my ($self, $tag, $value) = @_;
104 6         20 $self->{values}->{$tag} = $value;
105             }
106              
107             sub set_original {
108 14     14   25 my ($self, $value) = @_;
109 14         69 $self->{values}->{_original} = $value;
110             }
111              
112             sub set_tag {
113 6     6   19 my ($self, $tag) = @_;
114 6         16 $self->{tag} = $tag;
115             }
116              
117             sub original {
118 0     0   0 my $self = shift;
119 0         0 return $self->{values}->{_original};
120             }
121              
122             sub valid {
123 12     12   55 my $self = shift;
124 12         164 return $self->{tag};
125             }
126              
127             sub invalid {
128 4     4   11532 my $self = shift;
129 4         12 return $self->guess_error_tag_to_match;
130             }
131              
132             sub is_valid {
133 0     0   0 my $self = shift;
134 0 0       0 return ($self->{tag})? 1: 0;
135             }
136              
137             sub tag {
138 3     3   3 my $self = shift;
139 3         12 return $self->{tag};
140             }
141              
142             sub values {
143 3     3   1897 my $self = shift;
144              
145 3         14 my $tag = $self->tag;
146 3         24 return $self->{values}->{$tag};
147             }
148              
149             sub error {
150 4     4   2229 my ($self, $tag) = @_;
151              
152 4         17 my $errors = $self->errors($tag);
153              
154 4 50       13 return undef unless $errors;
155 4         34 return $errors->[0];
156             }
157              
158             sub errors {
159 16     16   51707 my ($self, $tag) = @_;
160              
161 16 100       50 unless ($tag) {
162 4         14 $tag = $self->guess_error_tag_to_match;
163             }
164 16   50     137 return $self->{errors}->{$tag} || [];
165             }
166              
167             sub guess_error_tag_to_match {
168 8     8   56 my ($self) = @_;
169              
170 8         11 my %diff;
171 8         14 for my $tag (reverse @{$self->{priority}}) {
  8         24  
172 16 50       53 if (my $errors = $self->{errors}->{$tag}) {
173 16         27 my $error_size = scalar @$errors;
174 16         51 $diff{$error_size} = $tag;
175             }
176             }
177 8         32 my $min = (sort keys %diff)[0];
178 8         45 return $diff{$min};
179             }
180              
181             1;
182             __END__