File Coverage

blib/lib/Data/YADV/Checker.pm
Criterion Covered Total %
statement 63 64 98.4
branch 17 22 77.2
condition 2 3 66.6
subroutine 21 22 95.4
pod 0 8 0.0
total 103 119 86.5


line stmt bran cond sub pod time code
1             package Data::YADV::Checker;
2              
3 1     1   2281 use strict;
  1         2  
  1         50  
4 1     1   6 use warnings;
  1         2  
  1         29  
5              
6 1     1   2381 use Try::Tiny;
  1         1825  
  1         82  
7 1     1   675 use Data::YADV::CheckerASub;
  1         4  
  1         919  
8              
9             sub new {
10 23     23 0 76 my ($class, $structure, %args) = @_;
11              
12 23         177 bless {structure => $structure, %args}, $class;
13             }
14              
15 34     34 0 168 sub structure { $_[0]->{structure} }
16 16     16 0 89 sub schema { $_[0]->{schema} }
17              
18             sub check {
19 2     2 0 22 my $self = shift;
20 2 50       135 my ($structure, $factory) = $self->_prepare_arguments(@_) or return;
21              
22 2         6 $factory->($structure)->verify();
23             }
24              
25             sub check_value {
26 4     4 0 39 my $self = shift;
27 4         6 my $cb = pop;
28 4 50       18 my $child = $self->_prepare_structure(@_) or return;
29              
30 4         18 $self->schema->build_checker('Data::YADV::CheckerASub', $cb => $child)
31             ->verify();
32             }
33              
34             sub check_defined {
35 6     6 0 30 my $self = shift;
36 6 100       35 my $structure = $self->_prepare_structure(@_) or return;
37              
38 4 100       22 if (not defined $structure->get_structure) {
39 1         8 $self->error('element not defined', @_);
40             }
41             }
42              
43             sub check_each {
44 4     4 0 42 my $self = shift;
45 4 50       26 my ($node, $factory) = $self->_prepare_arguments(@_) or return;
46              
47 1         12 return $self->error($node->get_type . ' is not iterable',
48 4 100       45 @{$node->get_path})
49             unless $node->can('each');
50              
51             $node->each(
52             sub {
53 6     6   12 my ($node, $key) = @_;
54 6         19 $factory->($node)->verify($key);
55             }
56 3         22 );
57             }
58              
59             sub _get_child {
60 16     16   33 my ($self, $structure, @path) = @_;
61              
62             my $child = try {
63 16     16   495 $structure->get_child(@path);
64             }
65             catch {
66 0     0   0 $self->_error_against_structure($structure, $_, @path);
67 16         136 };
68              
69 16 100       270 $self->_error_against_structure($structure, 'element not found', @path) unless defined $child;
70              
71 16         77 $child;
72             }
73              
74             sub _prepare_structure {
75 16     16   32 my ($self, @elements) = @_;
76              
77 16         22 my $structure = $elements[0];
78 16 100 66     63 if (ref $structure && $structure->can('get_child')) {
79 2         4 shift @elements;
80             } else {
81 14         64 $structure = $self->structure;
82             }
83              
84 16         69 $self->_get_child($structure, @elements);
85             }
86              
87             sub _prepare_arguments {
88 6     6   15 my ($self, @elements) = @_;
89 6         11 my $schema = pop @elements;
90              
91 6 50       30 my $structure = $self->_prepare_structure(@elements) or return;
92 6         53 my $checker_factory = $self->_checker_factory($schema);
93              
94 6         26 ($structure, $checker_factory);
95             }
96              
97             sub _checker_factory {
98 6     6   10 my ($self, $schema) = @_;
99              
100 6 100       17 if (ref $schema eq 'CODE') {
101             return sub {
102 4     4   19 $self->schema->build_checker('Data::YADV::CheckerASub', $schema,
103             @_);
104             }
105 3         15 }
106              
107             return sub {
108 4     4   17 my $module = $self->schema->schema_to_module($schema);
109 4         66 $self->schema->build_checker($module, @_);
110 3         15 };
111             }
112              
113             sub error {
114 10     10 0 59 my $self = shift;
115              
116 10         19 $self->_error_against_structure($self->structure, @_);
117             }
118              
119             sub _error_against_structure {
120 12     12   26 my ($self, $structure, $message, @path) = @_;
121              
122 12         56 my $prefix = $structure->get_path_string(@path);
123 12 50       37 $prefix = '$structure' . ($prefix ? '->' : '') . $prefix;
124              
125 12         33 $self->{error_cb}->($prefix, $message);
126             }
127              
128             1;