File Coverage

blib/lib/Data/Transpose/Validator/Base.pm
Criterion Covered Total %
statement 50 51 98.0
branch 13 14 92.8
condition n/a
subroutine 12 12 100.0
pod 7 7 100.0
total 82 84 97.6


line stmt bran cond sub pod time code
1             package Data::Transpose::Validator::Base;
2              
3 14     14   9854 use strict;
  14         27  
  14         379  
4 14     14   66 use warnings;
  14         22  
  14         367  
5              
6 14     14   68 use Moo;
  14         23  
  14         110  
7 14     14   3956 use MooX::Types::MooseLike::Base qw(:all);
  14         25  
  14         6059  
8 14     14   78 use namespace::clean;
  14         23  
  14         84  
9              
10             =head1 NAME
11              
12             Data::Transpose::Validator::Base - Base class for Data::Transpose::Validator
13              
14             =head1 SYNOPSIS
15              
16             my $v = Data::Transpose::Validator::Base->new;
17             ok($v->is_valid("string"), "A string is valid");
18             ok($v->is_valid([]), "Empty array is valid");
19             ok($v->is_valid({}), "Empty hash is valid");
20             ok(!$v->is_valid(undef), "undef is not valid");
21              
22             =cut
23              
24             =head1 METHODS (to be overwritten by the subclasses)
25              
26             =head2 new()
27              
28             Constructor. It accepts an hash with the options.
29              
30             =head2 required
31              
32             Set or retrieve the required option. Returns true if required, false
33             otherwise.
34              
35             =cut
36              
37             has required => (is => 'rw',
38             isa => Bool,
39             default => sub { 0 });
40              
41             =head2 dtv_options
42              
43             Set or retrieve the Data::Transpose::Validator options. Given that the
44             various classes have a different way to initialize the objects, this
45             should be done only once the object has been built.
46              
47             E.g.
48              
49             my $obj = $class->new(%classoptions);
50             $obj->dtv_options(\%dtv_options);
51              
52             =cut
53              
54             has dtv_options => (is => 'rw',
55             isa => Maybe[HashRef]);
56              
57             =head2 dtv_value
58              
59             On transposing, the value of the field is stored here.
60              
61             =cut
62              
63             has dtv_value => (is => 'rw');
64              
65             around dtv_value => sub {
66             my $orig = shift;
67             my $ret = $orig->(@_);
68             defined $ret ? return $ret : return '';
69             };
70              
71             has _error => (is => 'rw',
72             isa => ArrayRef,
73             default => sub { [] },
74             );
75              
76              
77             has _warnings => (is => 'rw',
78             isa => ArrayRef,
79             default => sub { [] });
80              
81              
82             =head2 reset_dtv_value
83              
84             Delete the dtv_value from the object
85              
86             =cut
87              
88             sub reset_dtv_value {
89 357     357 1 8573 shift->dtv_value(undef);
90             }
91              
92              
93             =head2 is_valid($what)
94              
95             Main method. Return true if the variable passed is defined, false if
96             it's undefined, storing an error.
97              
98             =cut
99              
100              
101             sub is_valid {
102 54     54 1 134 my ($self, $arg) = @_;
103 54         122 $self->reset_errors;
104 54 100       4487 if (defined $arg) {
105 53         190 return 1
106             } else {
107 1         5 $self->error("undefined");
108 1         10 return undef;
109             }
110             }
111              
112             =head2 error
113              
114             Main method to check why the validator returned false. When an
115             argument is provided, set the error.
116              
117             In scalar context it returns a human-readable string with the errors.
118              
119             In list context it returns the raw error list, where each element is a
120             pair of code and strings.
121              
122             =cut
123              
124             sub error {
125 3012     3012 1 8341 my ($self, $error) = @_;
126 3012 100       6046 if ($error) {
127 171         217 my $error_code_string;
128 171 100       629 if (ref($error) eq "") {
    50          
129 14         44 $error_code_string = [ $error => $error ];
130             }
131             elsif (ref($error) eq 'ARRAY') {
132 157         234 $error_code_string = $error;
133             }
134             else {
135 0         0 die "Wrong usage: error accepts strings or arrayrefs\n";
136             }
137 171         230 push @{$self->_error}, $error_code_string;
  171         4006  
138             }
139 3012         4469 my @errors = @{$self->_error};
  3012         64838  
140 3012 100       25263 return unless @errors;
141              
142 541         944 my $errorstring = join("; ", map { $_->[1] } @errors);
  805         2188  
143             # in scalar context, we stringify
144 541 100       2733 return wantarray ? @errors : $errorstring;
145             }
146              
147             =head2 reset_errors
148              
149             Clear the errors stored.
150              
151             =cut
152              
153             sub reset_errors {
154 589     589 1 12999 shift->_error([]);
155             }
156              
157             =head2 error_codes
158              
159             Returns the list of the error codes for the current validation.
160              
161             =cut
162              
163              
164             sub error_codes {
165 10     10 1 17 my $self = shift;
166 10         25 my @errors = $self->error;
167 10         13 my @out;
168 10         22 for (@errors) {
169 10         23 push @out, $_->[0];
170             }
171 10         28 return @out;
172             }
173              
174             =head2 warnings
175              
176             Set or retrieve a list of warnings issued by the validator.
177              
178             =head2 reset_warnings
179              
180             Reset the warning list.
181              
182             =cut
183              
184             sub warnings {
185 4     4 1 405 my ($self, @warn) = @_;
186 4 100       11 if (@warn) {
187 3         4 push @{$self->_warnings}, @warn;
  3         91  
188             }
189 4         18 return @{ $self->_warnings };
  4         125  
190             }
191              
192             sub reset_warnings {
193 14     14 1 370 shift->_warnings([]);
194             }
195              
196              
197             1;