File Coverage

blib/lib/Form/Tiny/Plugin/Strict.pm
Criterion Covered Total %
statement 52 52 100.0
branch 14 14 100.0
condition n/a
subroutine 10 10 100.0
pod 1 1 100.0
total 77 77 100.0


line stmt bran cond sub pod time code
1             package Form::Tiny::Plugin::Strict;
2             $Form::Tiny::Plugin::Strict::VERSION = '2.26';
3 19     19   259 use v5.10;
  19         69  
4 19     19   111 use strict;
  19         70  
  19         661  
5 19     19   89 use warnings;
  19         51  
  19         1129  
6              
7 19     19   109 use Form::Tiny::Error;
  19         88  
  19         625  
8 19     19   9262 use Form::Tiny::Path;
  19         77  
  19         833  
9              
10 19     19   149 use parent 'Form::Tiny::Plugin';
  19         37  
  19         144  
11              
12             sub plugin
13             {
14 32     32 1 105 my ($self, $caller, $context) = @_;
15              
16             return {
17 32         306 meta_roles => [__PACKAGE__],
18             };
19             }
20              
21 19     19   2264 use Moo::Role;
  19         59  
  19         222  
22              
23             requires qw(setup);
24              
25             # cache for the blueprint (if non-dynamic)
26             has '_strict_blueprint' => (
27             is => 'rw',
28             );
29              
30             sub _check_recursive
31             {
32 425     425   812 my ($self, $data, $blueprint) = @_;
33 425 100       955 return [{path => Form::Tiny::Path->empty, error => 'unexpected'}]
34             unless defined $blueprint;
35              
36 400 100       1146 if (ref $blueprint eq 'ARRAY') {
    100          
37 53 100       142 return [{path => Form::Tiny::Path->empty, error => 'not an array'}]
38             unless ref $data eq 'ARRAY';
39              
40 47         75 my @errors;
41 47         121 foreach my $key (0 .. $#$data) {
42 91         234 my $err = $self->_check_recursive($data->[$key], $blueprint->[0]);
43             push @errors, map {
44 91         190 $_->{path}->prepend(ARRAY => $key);
  10         31  
45 10         26 $_;
46             } @$err;
47             }
48              
49 47         103 return \@errors;
50             }
51             elsif (ref $blueprint eq 'HASH') {
52 203 100       729 return [{path => Form::Tiny::Path->empty, error => 'not an object'}]
53             unless ref $data eq 'HASH';
54              
55 194         387 my @errors;
56 194         584 for my $key (keys %$data) {
57 212         647 my $err = $self->_check_recursive($data->{$key}, $blueprint->{$key});
58             push @errors, map {
59 212         572 $_->{path}->prepend(HASH => $key);
  61         195  
60 61         208 $_;
61             } @$err;
62             }
63              
64 194         513 return \@errors;
65             }
66             else {
67             # we're at leaf and no error occured - we're good.
68             }
69              
70 144         307 return [];
71             }
72              
73             sub _check_strict
74             {
75 122     122   258 my ($self, $obj, $input) = @_;
76              
77 122         309 my $blueprint = $self->_strict_blueprint;
78 122 100       316 if (!$blueprint) {
79 20         170 $blueprint = $self->blueprint($obj, recurse => 0);
80 20 100       238 $self->_strict_blueprint($blueprint)
81             unless $self->is_dynamic;
82             }
83              
84 122         189 my @unexpected_field;
85 122         365 my $errors = $self->_check_recursive($input, $blueprint, \@unexpected_field);
86 122         354 foreach my $err (@$errors) {
87             $obj->add_error(
88             $self->build_error(
89             'IsntStrict',
90             extra_field => $err->{path}->join,
91             error => $err->{error},
92             )
93 40         139 );
94             }
95              
96 122         730 return $input;
97             }
98              
99             after 'setup' => sub {
100             my ($self) = @_;
101              
102             $self->add_hook(
103             Form::Tiny::Hook->new(
104             hook => 'before_validate',
105             code => sub { $self->_check_strict(@_) },
106             inherited => 0,
107             )
108             );
109             };
110              
111             1;
112