File Coverage

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


line stmt bran cond sub pod time code
1             package FormValidator::Simple::Struct;
2 10     10   207963 use 5.008_001;
  10         39  
3 10     10   54 use strict;
  10         18  
  10         219  
4 10     10   49 use warnings;
  10         27  
  10         302  
5 10     10   5685 use FormValidator::Simple::Struct::Regex;
  10         28  
  10         1179  
6 10     10   6056 use FormValidator::Simple::Struct::CharTypes;
  10         27  
  10         1841  
7 10     10   57 use Carp;
  10         19  
  10         540  
8 10     10   58 use Test::More;
  10         42  
  10         110  
9 10     10   12951 use Data::Dumper;
  10         64700  
  10         605  
10 10     10   7891 use Class::Load;
  10         211183  
  10         2951  
11              
12             our $VERSION = '0.16';
13              
14             # static values
15 2     2 0 7 sub HASHREF {'excepted hash ref'};
16 6     6 0 20 sub HASHVALUE {'excepted hash value'};
17 2     2 0 54 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 108 sub INVALID{'excepted ' . $_[0]};
21              
22 4     4 0 9 sub LENGTH_ERROR{'LENGTH IS WRONG'};
23 2     2 0 11 sub DIGIT_LENGTH_ERROR{'DIGIT_LENGTH IS WRONG'};
24 7     7 0 13 sub BETWEEN_ERROR{'BETWEEN IS WRONG'};
25 10     10 0 19 sub CHARS_ERROR{'NOT ALLOWED CHAR EXIST'};
26              
27             sub new{
28 8     8 0 121 my $class = bless {} , $_[0];
29 8         48 $class->load_plugin('FormValidator::Simple::Struct::CharTypes');
30 8         28 $class->load_plugin('FormValidator::Simple::Struct::Regex');
31 8         28 $class->load_plugin('FormValidator::Simple::Struct::AllowCharacter');
32 8         28 $class;
33             }
34              
35             sub load_plugin {
36 24     24 0 61 my ($class, $pkg, $opt) = @_;
37 24         97 Class::Load::load_class($pkg);
38 10     10   111 no strict 'refs';
  10         27  
  10         9361  
39 24         1846 for my $meth ( @{"${pkg}::EXPORT"} ) {
  24         136  
40             my $dest_meth =
41             ( $opt->{alias} && $opt->{alias}->{$meth} )
42 200 50 33     641 ? $opt->{alias}->{$meth}
43             : $meth;
44 200         231 *{"${class}::${dest_meth}"} = *{"${pkg}::$meth"};
  200         1392  
  200         733  
45             }
46             }
47              
48             sub check{
49 131     131 1 1433 my($self , $param , $rule) = @_;
50              
51 131         253 $self->{error} = 1;
52 131 50 33     560 croak('set params') if !$param or !$rule;
53              
54 131         207 $self->{error} = 0;
55 131         273 $self->{error_object} = [];
56 131         464 $self->_check($param , $param , $rule , '$param');
57            
58 131         713 !$self->{error};
59             }
60              
61             sub _check{
62 328     328   633 my($self , $param , $parent_params , $rule , $position , $name) = @_;
63              
64 328 100       820 if(ref $param eq 'Hash::MultiValue'){
65 2         9 $param = $param->as_hashref;
66             }
67              
68 328 100       660 if(ref $param){
69 146         244 my $ref = ref $rule;
70 146 100       375 if(ref $param ne $ref){
71 2 100       9 if($ref eq 'ARRAY'){
    50          
72 1         4 $self->_set_error(HASHREF, $position , $name);
73             }elsif($ref eq 'HASH'){
74 1         4 $self->_set_error(ARRAYREF, $position , $name);
75             }else{
76 0         0 croak('declareother types : HASH or ARRAY');
77             }
78             }else{
79 144 100       327 if($ref eq 'HASH'){
    50          
80 119         373 for(keys %$rule){
81 154 100       355 unless(exists $param->{$_}){
82 9 100 66     64 if(ref $rule->{$_} eq 'ARRAY' and ref $rule->{$_}[0] eq 'ARRAY'){
83 1         4 $self->_set_error(ARRAYREF, $position, $_ ,'NOT_BLANK');
84             }else{
85 8 100       22 if(_instr($rule->{$_},'NOT_BLANK')){
86 6         19 $self->_set_error(HASHVALUE, $position, $_ ,'NOT_BLANK');
87             }
88             }
89             }else{
90 145         644 $self->_check($param->{$_} , $param , $rule->{$_} , $position . "->{$_}" , $_);
91             }
92             }
93             }elsif($ref eq 'ARRAY'){
94 25 100 100     92 if(@$rule != 1 && @$rule != @$param){
95 2         11 $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         29 for(0..$#{$param}){
  23         81  
102 52 100       114 if(defined $rule->[$_]){
103 30   100     182 $self->_check($param->[$_] || "" , $param , $rule->[$_] , $position . "->[$_]" , $name);
104             }else{
105 22   50     128 $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       580 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       395 if($rule->[0] eq 'CHARTYPE'){
    50          
118 4         25 my (undef , @allow_chars) = @$rule;
119            
120 4         13 my $range = '';
121 4         12 for my $chars_name(@allow_chars){
122 10         70 my $code = $self->can("CHARTYPE::$chars_name");
123 10 50       39 die NO_SUCH_CHAR_TYPE($chars_name) unless $code;
124 10         47 $range .= $code->();
125             }
126            
127 4 50       195 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         220 for(@$rule){
138 214 100       519 if (ref $_ eq 'ARRAY'){
    100          
139 62         135 my ($type , $min , $max) = @$_;
140 62 100 66     494 if($min && $min !~ /^\d+\.\d+$|^\d+$/){
141 33         65 $min = $parent_params->{$min}
142             }
143 62 100 100     259 if($max && $max !~ /^\d+\.\d+$|^\d+$/){
144 7         13 $max = $parent_params->{$max}
145             }
146              
147 62 100       148 $max = $min unless defined $max;
148              
149 62 100 100     320 if($type eq 'LENGTH' or $type eq 'BETWEEN'){
    100          
    100          
    50          
150 26 50       56 if($max < $min ){
151 0         0 ($max , $min) = ($min , $max);
152             }
153 10     10   65 no strict;
  10         22  
  10         1138  
154              
155 26         76 my $code = $self->can($type);
156 26 50       62 die NO_SUCH_CHAR_TYPE($type) unless $code;
157 26 100       76 unless($code->($param,$min,$max)){
158 11         22 my $message;
159 11 100       34 if($type eq 'LENGTH'){
160 4         12 $message = LENGTH_ERROR;
161             }else{
162 7         14 $message = BETWEEN_ERROR;
163             }
164 11         32 $self->_set_error($message, $position , $name , $type, $min , $max);
165             }
166             }elsif($type eq 'DIGIT_LENGTH'){
167 10     10   54 no strict;
  10         22  
  10         7881  
168              
169 3         16 my $code = $self->can($type);
170 3 50       8 die NO_SUCH_CHAR_TYPE($type) unless $code;
171 3 100       11 unless($code->($param,$min,$max)){
172 2         11 my $message = DIGIT_LENGTH_ERROR;
173 2         9 $self->_set_error($message, $position , $name , $type, $min , $max);
174             }
175             }elsif($type eq 'CHARTYPE'){
176 27         69 my (undef , @allow_chars) = @$_;
177            
178 27         46 my $range = '';
179 27         50 for my $chars_name(@allow_chars){
180 30         199 my $code = $self->can("CHARTYPE::$chars_name");
181 30 50       84 die NO_SUCH_CHAR_TYPE($chars_name) unless $code;
182 30         103 $range .= $code->();
183             }
184            
185 27 100       494 if ($param =~ m/[$range]/){
186 10         33 my $message = CHARS_ERROR;
187 10         31 $self->_set_error($message, $position , $name , '');
188             }
189             }elsif($type eq 'ALLOWCHARACTER'){
190 6         15 my (undef , @allow_chars) = @$_;
191 6         12 for my $allow_char_method(@allow_chars){
192 6         26 my $code = $self->can("ALLOWCHARACTER::$allow_char_method");
193 6         16 my $replace_string = $code->();
194 6         46 $param =~ s/$replace_string//g;
195             }
196             }else{
197 0         0 croak "Not declare type:" . $type;
198             }
199             }elsif (ref $_){
200 1         5 $self->_set_error(HASHREF, $position , $name ,'ARRAY');
201 1         5 return;
202             }else{
203 151         444 my $code = $self->can($_);
204 151 50       316 die NO_SUCH_CHAR_TYPE($_) unless $code;
205 151 100       449 unless($code->($param)){
206 15         37 $self->_set_error(INVALID($_), $position , $name , $_);
207             }
208             }
209             }
210             }
211             }else{
212 67         193 my $code = $self->can($rule);
213 67 50       157 die NO_SUCH_CHAR_TYPE($rule) unless $code;
214 67 100       204 unless($code->($param)){
215 16         34 $self->_set_error(INVALID($rule), $position , $param , $rule);
216             }
217             }
218             }
219             }
220              
221             sub has_error{
222 18     18 1 78 $_[0]->{error};
223             }
224              
225             sub _set_error{
226 66     66   137 my ($self,$message,$position,$param_name,$error,$min,$max) = @_;
227 66         110 $self->{error} = 1;
228 66   50     169 $self->{error_object} ||= [];
229 66         94 push @{$self->{error_object}} , {
  66         639  
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 9663 $_[0]->{error_object} ||= [];
238             }
239              
240             sub _instr{
241 8     8   14 my ($array , $word) = @_;
242 8         22 for(@$array){
243 12 100       34 if($_ eq $word){
244 6         21 return 1;
245             }
246             }
247 2         12 return 0;
248             }
249              
250             1;
251             __END__