File Coverage

blib/lib/oCLI/Plugin/Validate.pm
Criterion Covered Total %
statement 9 39 23.0
branch 0 12 0.0
condition 0 3 0.0
subroutine 3 6 50.0
pod 0 3 0.0
total 12 63 19.0


line stmt bran cond sub pod time code
1             package oCLI::Plugin::Validate;
2 1     1   2423 use Moo;
  1         3  
  1         6  
3 1     1   1513 use Storable qw( dclone );
  1         3683  
  1         95  
4 1     1   22 use Scalar::Util qw( looks_like_number );
  1         3  
  1         851  
5              
6             # Enable code references in dclone so that our validation code
7             # refs don't result in "Can't store CODE items at"
8             # https://metacpan.org/pod/release/AMS/Storable-2.21/Storable.pm#CODE-REFERENCES
9             $Storable::Deparse = 1;
10             $Storable::Eval = 1;
11              
12             has tests => (
13             is => 'ro',
14             default => sub {
15             return +{
16             def => sub { defined $_[2] ? $_[2] : $_[3] },
17             defined => sub { defined $_[2] or die "Error: --$_[1] was expected.\n"; $_[2] },
18             num => sub { looks_like_number($_[2] or die "Error: --$_[1] expects a number.\n"); $_[2] },
19             gte => sub { $_[2] >= $_[3] or die "Error: --$_[1] must be a number greater than or equal to $_[3].\n"; $_[2] },
20             lte => sub { $_[2] <= $_[3] or die "Error: --$_[1] must be a number less than or equal to $_[3].\n"; $_[2] },
21             min => sub { length($_[2]) >= $_[3] or die "Error: --$_[1] must be a string longer than $_[3] characters.\n"; $_[2] },
22             max => sub { length($_[2]) <= $_[3] or die "Error: --$_[1] must be a string shorter than $_[3] characters.\n"; $_[2] },
23             };
24             }
25             );
26              
27       0 0   sub after_context { }
28              
29             # This function is run before the code reference is called.
30             #
31             # Self is the object of this code.
32             # c is the context object, it can be modified before running the code
33             # d is the command structure that we're running
34             sub before_code {
35 0     0 0   my ( $self, $c, $d ) = @_;
36              
37 0 0 0       if ( ( not $d->{validate} ) or ( ref($d->{validate}) ne 'ARRAY' ) ) {
38 0           $c->trace("No validation structure to check, skipping");
39 0           return;
40             }
41              
42 0           my $validate = dclone( $d->{validate} );
43              
44 0           while ( defined( my $token = shift @{$validate} ) ) {
  0            
45 0           $c->trace("Checking $token");
46            
47 0           my $meta = shift @{$validate};
  0            
48              
49 0           foreach my $test ( @{$meta->[0]} ) {
  0            
50 0           my ( $ref, $value );
51              
52              
53 0 0         if ( looks_like_number($token) ) {
54 0           $ref = \$c->req->args->[$token];
55 0           $value = $c->req->args->[$token];
56             } else {
57 0           $ref = \$c->req->settings->{$token};
58 0           $value = $c->req->settings->{$token};
59             }
60              
61 0 0         if ( ref($test) eq 'CODE' ) {
62 0           $c->trace("Running validation code block.");
63 0           $$ref = $test->($c, $token, $value);
64 0           next;
65             }
66              
67 0 0         if ( index($test, '=') != -1 ) {
68 0           my ( $function, $arg ) = split(/=/, $test, 2);
69 0           $c->trace("Running validation function $function with user-supplied value $arg.");
70              
71             die "Error: unknown function $function called in validation."
72 0 0         unless defined $self->tests->{$function};
73 0           $$ref = $self->tests->{$function}->($c, $token, $value, $arg );
74 0           next;
75             }
76              
77             # Last case, a bare function name.
78             die "Error: unknown function $test called in validation."
79 0 0         unless defined $self->tests->{$test};
80              
81 0           $$ref = $self->tests->{$test}->($c, $token, $value);
82             }
83              
84             }
85             }
86              
87       0 0   sub after_code {
88              
89             }
90              
91             1;