File Coverage

blib/lib/FormValidator/Simple/Struct.pm
Criterion Covered Total %
statement 153 166 92.1
branch 65 80 81.2
condition 15 23 65.2
subroutine 28 30 93.3
pod 3 15 20.0
total 264 314 84.0


line stmt bran cond sub pod time code
1             package FormValidator::Simple::Struct;
2 10     10   237063 use 5.008_001;
  10         39  
  10         436  
3 10     10   56 use strict;
  10         24  
  10         354  
4 10     10   54 use warnings;
  10         23  
  10         339  
5 10     10   6804 use FormValidator::Simple::Struct::Regex;
  10         28  
  10         1231  
6 10     10   6571 use FormValidator::Simple::Struct::CharTypes;
  10         26  
  10         1668  
7 10     10   58 use Carp;
  10         16  
  10         607  
8 10     10   53 use Test::More;
  10         33  
  10         101  
9 10     10   14333 use Data::Dumper;
  10         72974  
  10         765  
10 10     10   9563 use Class::Load;
  10         335346  
  10         2861  
11              
12             our $VERSION = '0.14';
13              
14             # static values
15 2     2 0 8 sub HASHREF {'excepted hash ref'};
16 6     6 0 20 sub HASHVALUE {'excepted hash value'};
17 2     2 0 47 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 135 sub INVALID{'excepted ' . $_[0]};
21              
22 4     4 0 10 sub LENGTH_ERROR{'LENGTH IS WRONG'};
23 2     2 0 15 sub DIGIT_LENGTH_ERROR{'DIGIT_LENGTH IS WRONG'};
24 5     5 0 13 sub BETWEEN_ERROR{'BETWEEN IS WRONG'};
25 9     9 0 18 sub CHARS_ERROR{'NOT ALLOWED CHAR EXIST'};
26              
27             sub new{
28 8     8 0 168 my $class = bless {} , $_[0];
29 8         61 $class->load_plugin('FormValidator::Simple::Struct::CharTypes');
30 8         30 $class->load_plugin('FormValidator::Simple::Struct::Regex');
31 8         29 $class->load_plugin('FormValidator::Simple::Struct::AllowCharacter');
32 8         33 $class;
33             }
34              
35             sub load_plugin {
36 24     24 0 160 my ($class, $pkg, $opt) = @_;
37 24         105 Class::Load::load_class($pkg);
38 10     10   104 no strict 'refs';
  10         23  
  10         8429  
39 24         1797 for my $meth ( @{"${pkg}::EXPORT"} ) {
  24         145  
40 192 50 33     1157 my $dest_meth =
41             ( $opt->{alias} && $opt->{alias}->{$meth} )
42             ? $opt->{alias}->{$meth}
43             : $meth;
44 192         264 *{"${class}::${dest_meth}"} = *{"${pkg}::$meth"};
  192         1499  
  192         821  
45             }
46             }
47              
48             sub check{
49 123     123 1 1259 my($self , $param , $rule) = @_;
50              
51 123         231 $self->{error} = 1;
52 123 50 33     571 croak('set params') if !$param or !$rule;
53              
54 123         187 $self->{error} = 0;
55 123         241 $self->{error_object} = [];
56 123         627 $self->_check($param,$rule,'$param');
57            
58 123         759 !$self->{error};
59             }
60              
61             sub _check{
62 308     308   540 my($self , $param , $rule , $position , $name) = @_;
63              
64 308 100       729 if(ref $param eq 'Hash::MultiValue'){
65 2         7 $param = $param->as_hashref;
66             }
67              
68 308 100       750 if(ref $param){
69 138         204 my $ref = ref $rule;
70 138 100       272 if(ref $param ne $ref){
71 2 100       15 if($ref eq 'ARRAY'){
    50          
72 1         3 $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 136 100       290 if($ref eq 'HASH'){
    50          
80 111         305 for(keys %$rule){
81 142 100       274 unless(exists $param->{$_}){
82 9 100 66     62 if(ref $rule->{$_} eq 'ARRAY' and ref $rule->{$_}[0] eq 'ARRAY'){
83 1         12 $self->_set_error(ARRAYREF, $position, $_ ,'NOT_BLANK');
84             }else{
85 8 100       26 if(_instr($rule->{$_},'NOT_BLANK')){
86 6         24 $self->_set_error(HASHVALUE, $position, $_ ,'NOT_BLANK');
87             }
88             }
89             }else{
90 133         603 $self->_check($param->{$_} , $rule->{$_} , $position . "->{$_}" , $_);
91             }
92             }
93             }elsif($ref eq 'ARRAY'){
94 25 100 100     112 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         7 return;
100             }
101 23         35 for(0..$#{$param}){
  23         80  
102 52 100       141 if(defined $rule->[$_]){
103 30   100     281 $self->_check($param->[$_] || "" , $rule->[$_] , $position . "->[$_]" , $name);
104             }else{
105 22   50     118 $self->_check($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 170 50       496 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 103 100       281 if($rule->[0] eq 'CHARTYPE'){
    50          
118 4         8 my (undef , @allow_chars) = @$rule;
119            
120 4         6 my $range = '';
121 4         9 for my $chars_name(@allow_chars){
122 10         39 my $code = $self->can("CHARTYPE::$chars_name");
123 10 50       20 die NO_SUCH_CHAR_TYPE($chars_name) unless $code;
124 10         29 $range .= $code->();
125             }
126            
127 4 50       87 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 99         170 for(@$rule){
138 186 100       395 if (ref $_ eq 'ARRAY'){
    100          
139 50         88 my ($type,$min,$max) = @$_;
140            
141 50 100       115 $max = $min unless defined $max;
142              
143 50 100 100     257 if($type eq 'LENGTH' or $type eq 'BETWEEN'){
    100          
    100          
    50          
144 18 50       46 if($max < $min ){
145 0         0 ($max , $min) = ($min , $max);
146             }
147 10     10   67 no strict;
  10         17  
  10         1159  
148              
149 18         66 my $code = $self->can($type);
150 18 50       43 die NO_SUCH_CHAR_TYPE($type) unless $code;
151 18 100       57 unless($code->($param,$min,$max)){
152 9         13 my $message;
153 9 100       22 if($type eq 'LENGTH'){
154 4         12 $message = LENGTH_ERROR;
155             }else{
156 5         14 $message = BETWEEN_ERROR;
157             }
158 9         28 $self->_set_error($message, $position , $name , $type, $min , $max);
159             }
160             }elsif($type eq 'DIGIT_LENGTH'){
161 10     10   58 no strict;
  10         19  
  10         7546  
162              
163 3         14 my $code = $self->can($type);
164 3 50       7 die NO_SUCH_CHAR_TYPE($type) unless $code;
165 3 100       17 unless($code->($param,$min,$max)){
166 2         4 my $message = DIGIT_LENGTH_ERROR;
167 2         7 $self->_set_error($message, $position , $name , $type, $min , $max);
168             }
169             }elsif($type eq 'CHARTYPE'){
170 23         46 my (undef , @allow_chars) = @$_;
171            
172 23         32 my $range = '';
173 23         35 for my $chars_name(@allow_chars){
174 25         123 my $code = $self->can("CHARTYPE::$chars_name");
175 25 50       64 die NO_SUCH_CHAR_TYPE($chars_name) unless $code;
176 25         86 $range .= $code->();
177             }
178            
179 23 100       399 if ($param =~ m/[$range]/){
180 9         25 my $message = CHARS_ERROR;
181 9         35 $self->_set_error($message, $position , $name , '');
182             }
183             }elsif($type eq 'ALLOWCHARACTER'){
184 6         11 my (undef , @allow_chars) = @$_;
185 6         9 for my $allow_char_method(@allow_chars){
186 6         25 my $code = $self->can("ALLOWCHARACTER::$allow_char_method");
187 6         17 my $replace_string = $code->();
188 6         54 $param =~ s/$replace_string//g;
189             }
190             }else{
191 0         0 croak "Not declare type:" . $type;
192             }
193             }elsif (ref $_){
194 1         5 $self->_set_error(HASHREF, $position , $name ,'ARRAY');
195 1         5 return;
196             }else{
197 135         378 my $code = $self->can($_);
198 135 50       286 die NO_SUCH_CHAR_TYPE($_) unless $code;
199 135 100       373 unless($code->($param)){
200 15         47 $self->_set_error(INVALID($_), $position , $name , $_);
201             }
202             }
203             }
204             }
205             }else{
206 67         385 my $code = $self->can($rule);
207 67 50       179 die NO_SUCH_CHAR_TYPE($rule) unless $code;
208 67 100       227 unless($code->($param)){
209 16         48 $self->_set_error(INVALID($rule), $position , $param , $rule);
210             }
211             }
212             }
213             }
214              
215             sub has_error{
216 18     18 1 97 $_[0]->{error};
217             }
218              
219             sub _set_error{
220 63     63   139 my ($self,$message,$position,$param_name,$error,$min,$max) = @_;
221 63         114 $self->{error} = 1;
222 63   50     167 $self->{error_object} ||= [];
223 63         90 push @{$self->{error_object}} , {
  63         654  
224             message => $message ,position => $position ,
225             param_name => $param_name , error => $error,
226             min_value => $min , max_value => $max ,
227             };
228             }
229              
230             sub get_error{
231 48   50 48 1 9736 $_[0]->{error_object} ||= [];
232             }
233              
234             sub _instr{
235 8     8   15 my ($array , $word) = @_;
236 8         17 for(@$array){
237 12 100       47 if($_ eq $word){
238 6         21 return 1;
239             }
240             }
241 2         14 return 0;
242             }
243              
244             1;
245             __END__