File Coverage

blib/lib/Input/Validator/Field.pm
Criterion Covered Total %
statement 127 132 96.2
branch 67 76 88.1
condition 11 12 91.6
subroutine 24 24 100.0
pod 16 18 88.8
total 245 262 93.5


line stmt bran cond sub pod time code
1             package Input::Validator::Field;
2              
3 9     9   2842 use strict;
  9         20  
  9         340  
4 9     9   48 use warnings;
  9         16  
  9         302  
5              
6 9     9   57 use base 'Input::Validator::Base';
  9         20  
  9         1757  
7              
8 9     9   4939 use Input::Validator::Bulk;
  9         19  
  9         238  
9 9     9   843 use Input::Validator::ConstraintBuilder;
  9         19  
  9         17013  
10              
11             our $AUTOLOAD;
12              
13             sub BUILD {
14 52     52 0 79 my $self = shift;
15              
16 52   50     346 $self->{constraints} ||= [];
17 52   100     203 $self->{messages} ||= {};
18              
19 52 50       159 $self->{trim} = 1 unless defined $self->{trim};
20              
21 52         110 return $self;
22             }
23              
24             sub name {
25 82     82 1 103 my $self = shift;
26              
27 82 50       373 return $self->{name} unless @_;
28              
29 0         0 $self->{name} = $_[0];
30              
31 0         0 return $self;
32             }
33              
34             sub required {
35 110     110 1 140 my $self = shift;
36              
37 110 100       491 return $self->{required} unless @_;
38              
39 11         23 $self->{required} = $_[0];
40              
41 11         40 return $self;
42             }
43              
44             sub inflate {
45 93     93 1 126 my $self = shift;
46              
47 93 100       320 return $self->{inflate} unless @_;
48              
49 6         13 $self->{inflate} = $_[0];
50              
51 6         15 return $self;
52             }
53              
54             sub deflate {
55 58     58 1 81 my $self = shift;
56              
57 58 100       211 return $self->{deflate} unless @_;
58              
59 4         8 $self->{deflate} = $_[0];
60              
61 4         9 return $self;
62             }
63              
64             sub trim {
65 147     147 1 170 my $self = shift;
66              
67 147 50       537 return $self->{trim} unless @_;
68              
69 0         0 $self->{trim} = $_[0];
70              
71 0         0 return $self;
72             }
73              
74             sub error {
75 298     298 1 371 my $self = shift;
76              
77 298 100       937 return $self->{error} unless @_;
78              
79 193         370 $self->{error} = $_[0];
80              
81 193         372 return $self;
82             }
83              
84             sub constraint {
85 21     21 1 23 my $self = shift;
86              
87 21         114 my $constraint = Input::Validator::ConstraintBuilder->build(@_);
88              
89 21         26 push @{$self->{constraints}}, $constraint;
  21         50  
90              
91 21         62 return $self;
92             }
93              
94             sub messages {
95 4     4 1 10 my $self = shift;
96              
97 4 50       12 return $self->{messages} unless @_;
98              
99 4 50       17 my @messages = @_ == 1 ? %{$_[0]} : @_;
  0         0  
100              
101 4         10 my %new_messages = @messages;
102              
103 4         11 foreach my $message (keys %new_messages) {
104 4         15 $self->{messages}->{$message} = $new_messages{$message};
105             }
106              
107 4         16 return $self;
108             }
109              
110             sub error_to_message {
111 34     34 0 445 my $self = shift;
112 34         38 my $error = shift;
113 34   100     143 my $params = shift || [];
114              
115 34         63 my $message = $self->{messages}->{$error};
116 34 100       75 $message = $error unless defined $message;
117              
118 34         186 return sprintf($message, @$params);
119             }
120              
121             sub multiple {
122 502     502 1 601 my $self = shift;
123              
124 502 100       1817 return $self->{multiple} unless @_;
125              
126 17         59 $self->{multiple} = [splice @_, 0, 2];
127              
128 17         47 return $self;
129             }
130              
131             sub value {
132 622     622 1 877 my $self = shift;
133              
134 622 100       2433 return $self->{value} unless @_;
135              
136 166         227 my $value = shift;
137              
138 166 100       381 return unless defined $value;
139              
140 147 100       289 if ($self->multiple) {
141 37 100       121 $self->{value} = ref($value) eq 'ARRAY' ? $value : [$value];
142             }
143             else {
144 110 100       314 $self->{value} = ref($value) eq 'ARRAY' ? $value->[0] : $value;
145             }
146              
147 147 50       322 return $self unless $self->trim;
148              
149 147 100       353 foreach ($self->multiple ? @{$self->{value}} : $self->{value}) {
  37         90  
150 210         420 s/^\s+//;
151 210         522 s/\s+$//;
152             }
153              
154 147         396 return $self;
155             }
156              
157             sub is_valid {
158 99     99 1 162 my ($self) = @_;
159              
160 99         182 $self->error('');
161              
162 99 100 100     189 $self->error($self->error_to_message('REQUIRED')), return 0
163             if $self->required && $self->is_empty;
164              
165 87 100       179 return 1 if $self->is_empty;
166              
167 71 100       150 my @values = $self->multiple ? @{$self->value} : $self->value;
  20         35  
168              
169 71 100       155 @values = map { &{$self->inflate} } @values if $self->inflate;
  16         61  
  16         28  
170              
171 71 100       184 if (my $multiple = $self->multiple) {
172 20         33 my ($min, $max) = @$multiple;
173              
174 20 100       46 $self->error($self->error_to_message('NOT_ENOUGH')), return 0
175             if @values < $min;
176 18 100 100     81 $self->error($self->error_to_message('TOO_MUCH')), return 0
    100          
177             if defined $max ? @values > $max : $min != 1 && @values != $min;
178             }
179              
180 67         81 foreach my $c (@{$self->{constraints}}) {
  67         148  
181 43 100       161 if ($c->is_multiple) {
182 4         17 my ($ok, $error) = $c->is_valid([@values]);
183              
184 4 100       15 unless ($ok) {
185 2         13 $self->error($self->error_to_message($c->error, $error));
186 2         11 return 0;
187             }
188             }
189             else {
190 39         67 foreach my $value (@values) {
191 42         115 my ($ok, $error) = $c->is_valid($value);
192              
193 42 100       153 unless ($ok) {
194 16         73 $self->error($self->error_to_message($c->error, $error));
195 16         79 return 0;
196             }
197             }
198             }
199             }
200              
201 49 100       112 @values = map { &{$self->deflate} } @values if $self->deflate;
  5         9  
  5         11  
202              
203 49 100       122 $self->value($self->multiple ? \@values : $values[0]);
204              
205 49         207 return 1;
206             }
207              
208             sub clear_error {
209 1     1 1 2 my $self = shift;
210              
211 1         3 delete $self->{error};
212             }
213              
214             sub clear_value {
215 59     59 1 78 my $self = shift;
216              
217 59         157 delete $self->{value};
218             }
219              
220             sub each {
221 1     1 1 2 my $self = shift;
222              
223 1         11 my $bulk = Input::Validator::Bulk->new(fields => [$self]);
224 1         19 return $bulk->each(@_);
225             }
226              
227             sub is_defined {
228 118     118 1 136 my ($self) = @_;
229              
230 118 100       181 return defined $self->value ? 1 : 0;
231             }
232              
233             sub is_empty {
234 116     116 1 141 my ($self) = @_;
235              
236 116 100       189 return 1 unless $self->is_defined;
237              
238 92 100       188 if (ref $self->value eq 'ARRAY') {
239 24         25 return @{$self->value} == 0;
  24         51  
240             }
241              
242 68 100       131 return $self->value eq '' ? 1 : 0;
243             }
244              
245             sub AUTOLOAD {
246 21     21   182 my $self = shift;
247              
248 21         32 my $method = $AUTOLOAD;
249              
250 21 50       106 return if $method =~ /^[A-Z]+?$/;
251 21 50       89 return if $method =~ /^_/;
252 21 50       47 return if $method =~ /(?:\:*?)DESTROY$/;
253              
254 21         85 $method = (split '::' => $method)[-1];
255              
256 21         69 return $self->constraint($method => @_);
257             }
258              
259             1;
260             __END__