File Coverage

blib/lib/FormValidator/Simple/Struct.pm
Criterion Covered Total %
statement 157 170 92.3
branch 69 84 82.1
condition 20 29 68.9
subroutine 28 30 93.3
pod 3 15 20.0
total 277 328 84.4


line stmt bran cond sub pod time code
1             package FormValidator::Simple::Struct;
2 10     10   143051 use 5.008_001;
  10         28  
  10         346  
3 10     10   45 use strict;
  10         11  
  10         295  
4 10     10   42 use warnings;
  10         15  
  10         261  
5 10     10   3555 use FormValidator::Simple::Struct::Regex;
  10         23  
  10         976  
6 10     10   3968 use FormValidator::Simple::Struct::CharTypes;
  10         17  
  10         1453  
7 10     10   52 use Carp;
  10         13  
  10         464  
8 10     10   46 use Test::More;
  10         33  
  10         93  
9 10     10   8707 use Data::Dumper;
  10         48831  
  10         569  
10 10     10   4841 use Class::Load;
  10         218135  
  10         2239  
11              
12             our $VERSION = '0.15';
13              
14             # static values
15 2     2 0 8 sub HASHREF {'excepted hash ref'};
16 6     6 0 19 sub HASHVALUE {'excepted hash value'};
17 2     2 0 43 sub ARRAYREF {'excepted array ref'};
18 0     0 0 0 sub NO_SUCH_CHAR_TYPE {'was not declare ' . $_->[0]};
19 0     0 0 0 sub REF {'excepted ref'};
20 31     31 0 101 sub INVALID{'excepted ' . $_[0]};
21              
22 4     4 0 7 sub LENGTH_ERROR{'LENGTH IS WRONG'};
23 2     2 0 4 sub DIGIT_LENGTH_ERROR{'DIGIT_LENGTH IS WRONG'};
24 7     7 0 13 sub BETWEEN_ERROR{'BETWEEN IS WRONG'};
25 10     10 0 15 sub CHARS_ERROR{'NOT ALLOWED CHAR EXIST'};
26              
27             sub new{
28 8     8 0 107 my $class = bless {} , $_[0];
29 8         41 $class->load_plugin('FormValidator::Simple::Struct::CharTypes');
30 8         25 $class->load_plugin('FormValidator::Simple::Struct::Regex');
31 8         22 $class->load_plugin('FormValidator::Simple::Struct::AllowCharacter');
32 8         23 $class;
33             }
34              
35             sub load_plugin {
36 24     24 0 45 my ($class, $pkg, $opt) = @_;
37 24         77 Class::Load::load_class($pkg);
38 10     10   69 no strict 'refs';
  10         13  
  10         6439  
39 24         1279 for my $meth ( @{"${pkg}::EXPORT"} ) {
  24         105  
40 200 50 33     440 my $dest_meth =
41             ( $opt->{alias} && $opt->{alias}->{$meth} )
42             ? $opt->{alias}->{$meth}
43             : $meth;
44 200         142 *{"${class}::${dest_meth}"} = *{"${pkg}::$meth"};
  200         919  
  200         458  
45             }
46             }
47              
48             sub check{
49 131     131 1 1243 my($self , $param , $rule) = @_;
50              
51 131         197 $self->{error} = 1;
52 131 50 33     505 croak('set params') if !$param or !$rule;
53              
54 131         136 $self->{error} = 0;
55 131         185 $self->{error_object} = [];
56 131         337 $self->_check($param , $param , $rule , '$param');
57            
58 131         555 !$self->{error};
59             }
60              
61             sub _check{
62 328     328   409 my($self , $param , $parent_params , $rule , $position , $name) = @_;
63              
64 328 100       608 if(ref $param eq 'Hash::MultiValue'){
65 2         8 $param = $param->as_hashref;
66             }
67              
68 328 100       465 if(ref $param){
69 146         223 my $ref = ref $rule;
70 146 100       231 if(ref $param ne $ref){
71 2 100       19 if($ref eq 'ARRAY'){
    50          
72 1         4 $self->_set_error(HASHREF, $position , $name);
73             }elsif($ref eq 'HASH'){
74 1         5 $self->_set_error(ARRAYREF, $position , $name);
75             }else{
76 0         0 croak('declareother types : HASH or ARRAY');
77             }
78             }else{
79 144 100       233 if($ref eq 'HASH'){
    50          
80 119         307 for(keys %$rule){
81 154 100       263 unless(exists $param->{$_}){
82 9 100 66     68 if(ref $rule->{$_} eq 'ARRAY' and ref $rule->{$_}[0] eq 'ARRAY'){
83 1         5 $self->_set_error(ARRAYREF, $position, $_ ,'NOT_BLANK');
84             }else{
85 8 100       61 if(_instr($rule->{$_},'NOT_BLANK')){
86 6         20 $self->_set_error(HASHVALUE, $position, $_ ,'NOT_BLANK');
87             }
88             }
89             }else{
90 145         529 $self->_check($param->{$_} , $param , $rule->{$_} , $position . "->{$_}" , $_);
91             }
92             }
93             }elsif($ref eq 'ARRAY'){
94 25 100 100     76 if(@$rule != 1 && @$rule != @$param){
95 2         5 $self->_set_error(
96             '$rule\'s length differs from $param\'s length',
97             $position,
98             $name , 'ARRAY_LENGTH');
99 2         4 return;
100             }
101 23         18 for(0..$#{$param}){
  23         64  
102 52 100       84 if(defined $rule->[$_]){
103 30   100     149 $self->_check($param->[$_] || "" , $param , $rule->[$_] , $position . "->[$_]" , $name);
104             }else{
105 22   50     79 $self->_check($param->[$_] || "" , $param , $rule->[0] , $position . "->[$_]" , $name);
106             }
107             }
108             }else{
109 0         0 croak($ref . ':declare other types : HASH or ARRAY');
110             }
111             }
112             }else{
113 182 50       392 if(ref $rule eq 'HASH'){
    100          
114 0         0 $self->_set_error(HASHREF, $position , $name , 'HASH');
115 0         0 return;
116             }elsif(ref $rule eq 'ARRAY'){
117 115 100       282 if($rule->[0] eq 'CHARTYPE'){
    50          
118 4         12 my (undef , @allow_chars) = @$rule;
119            
120 4         5 my $range = '';
121 4         8 for my $chars_name(@allow_chars){
122 10         32 my $code = $self->can("CHARTYPE::$chars_name");
123 10 50       15 die NO_SUCH_CHAR_TYPE($chars_name) unless $code;
124 10         21 $range .= $code->();
125             }
126            
127 4 50       81 if ($param =~ m/[$range]/){
128 0         0 my $message = CHARS_ERROR;
129 0         0 $self->_set_error($message, $position , $name , '');
130             }
131             }elsif($rule->[0] eq 'ALLOWCHARACTER'){
132 0         0 my (undef , @allow_chars) = @$rule;
133 0         0 for(@allow_chars){
134 0         0 $param =~ s/$param/$_/g;
135             }
136             }else{
137 111         160 for(@$rule){
138 214 100       373 if (ref $_ eq 'ARRAY'){
    100          
139 62         79 my ($type , $min , $max) = @$_;
140 62 100 66     405 if($min && $min !~ /^\d+\.\d+$|^\d+$/){
141 33         46 $min = $parent_params->{$min}
142             }
143 62 100 100     187 if($max && $max !~ /^\d+\.\d+$|^\d+$/){
144 7         10 $max = $parent_params->{$max}
145             }
146              
147 62 100       112 $max = $min unless defined $max;
148              
149 62 100 100     246 if($type eq 'LENGTH' or $type eq 'BETWEEN'){
    100          
    100          
    50          
150 26 50       46 if($max < $min ){
151 0         0 ($max , $min) = ($min , $max);
152             }
153 10     10   54 no strict;
  10         18  
  10         944  
154              
155 26         56 my $code = $self->can($type);
156 26 50       46 die NO_SUCH_CHAR_TYPE($type) unless $code;
157 26 100       57 unless($code->($param,$min,$max)){
158 11         11 my $message;
159 11 100       20 if($type eq 'LENGTH'){
160 4         10 $message = LENGTH_ERROR;
161             }else{
162 7         14 $message = BETWEEN_ERROR;
163             }
164 11         25 $self->_set_error($message, $position , $name , $type, $min , $max);
165             }
166             }elsif($type eq 'DIGIT_LENGTH'){
167 10     10   43 no strict;
  10         14  
  10         5887  
168              
169 3         13 my $code = $self->can($type);
170 3 50       6 die NO_SUCH_CHAR_TYPE($type) unless $code;
171 3 100       14 unless($code->($param,$min,$max)){
172 2         6 my $message = DIGIT_LENGTH_ERROR;
173 2         5 $self->_set_error($message, $position , $name , $type, $min , $max);
174             }
175             }elsif($type eq 'CHARTYPE'){
176 27         48 my (undef , @allow_chars) = @$_;
177            
178 27         23 my $range = '';
179 27         33 for my $chars_name(@allow_chars){
180 30         112 my $code = $self->can("CHARTYPE::$chars_name");
181 30 50       55 die NO_SUCH_CHAR_TYPE($chars_name) unless $code;
182 30         70 $range .= $code->();
183             }
184            
185 27 100       387 if ($param =~ m/[$range]/){
186 10         19 my $message = CHARS_ERROR;
187 10         28 $self->_set_error($message, $position , $name , '');
188             }
189             }elsif($type eq 'ALLOWCHARACTER'){
190 6         10 my (undef , @allow_chars) = @$_;
191 6         9 for my $allow_char_method(@allow_chars){
192 6         20 my $code = $self->can("ALLOWCHARACTER::$allow_char_method");
193 6         14 my $replace_string = $code->();
194 6         47 $param =~ s/$replace_string//g;
195             }
196             }else{
197 0         0 croak "Not declare type:" . $type;
198             }
199             }elsif (ref $_){
200 1         3 $self->_set_error(HASHREF, $position , $name ,'ARRAY');
201 1         3 return;
202             }else{
203 151         344 my $code = $self->can($_);
204 151 50       252 die NO_SUCH_CHAR_TYPE($_) unless $code;
205 151 100       327 unless($code->($param)){
206 15         42 $self->_set_error(INVALID($_), $position , $name , $_);
207             }
208             }
209             }
210             }
211             }else{
212 67         133 my $code = $self->can($rule);
213 67 50       98 die NO_SUCH_CHAR_TYPE($rule) unless $code;
214 67 100       129 unless($code->($param)){
215 16         29 $self->_set_error(INVALID($rule), $position , $param , $rule);
216             }
217             }
218             }
219             }
220              
221             sub has_error{
222 18     18 1 72 $_[0]->{error};
223             }
224              
225             sub _set_error{
226 66     66   97 my ($self,$message,$position,$param_name,$error,$min,$max) = @_;
227 66         81 $self->{error} = 1;
228 66   50     143 $self->{error_object} ||= [];
229 66         65 push @{$self->{error_object}} , {
  66         505  
230             message => $message ,position => $position ,
231             param_name => $param_name , error => $error,
232             min_value => $min , max_value => $max ,
233             };
234             }
235              
236             sub get_error{
237 48   50 48 1 7701 $_[0]->{error_object} ||= [];
238             }
239              
240             sub _instr{
241 8     8   16 my ($array , $word) = @_;
242 8         15 for(@$array){
243 12 100       32 if($_ eq $word){
244 6         20 return 1;
245             }
246             }
247 2         10 return 0;
248             }
249              
250             1;
251             __END__