File Coverage

blib/lib/Valiemon/Attributes/Properties.pm
Criterion Covered Total %
statement 48 49 97.9
branch 13 14 92.8
condition 2 3 66.6
subroutine 11 11 100.0
pod 0 2 0.0
total 74 79 93.6


line stmt bran cond sub pod time code
1             package Valiemon::Attributes::Properties;
2 12     12   7219 use strict;
  12         51  
  12         379  
3 12     12   65 use warnings;
  12         45  
  12         287  
4 12     12   57 use utf8;
  12         23  
  12         64  
5 12     12   738 use parent qw(Valiemon::Attributes);
  12         312  
  12         60  
6              
7 12     12   898 use Carp qw(croak);
  12         37  
  12         678  
8 12     12   84 use Clone qw(clone);
  12         20  
  12         602  
9 12     12   1171 use List::MoreUtils qw(all);
  12         24779  
  12         85  
10 12     12   8667 use Valiemon;
  12         26  
  12         4519  
11              
12 189     189 0 571 sub attr_name { 'properties' }
13              
14             sub is_valid {
15 189     189 0 442 my ($class, $context, $schema, $data) = @_;
16             $context->in_attr($class, sub {
17 189 100   189   564 return 1 unless ref $data eq 'HASH'; # ignore
18              
19 183         335 my $properties = $schema->{properties};
20 183 50       411 unless (ref $properties eq 'HASH') {
21 0         0 croak sprintf '`properties` must be an object at %s', $context->position
22             }
23              
24 183         309 my $is_valid = 1;
25 183         496 for my $prop (keys %$properties) {
26 267 100       636 unless (exists $data->{$prop}) {
27             my $definition = $properties->{$prop}->{'$ref'} # resolve ref TODO refactor
28             ? $context->rv->resolve_ref($properties->{$prop}->{'$ref'})
29 81 100       244 : $properties->{$prop};
30 79 100 66     258 if (my $default = $definition->{default}) {
    100          
31             # fill in default
32 6         64 $data->{$prop} = clone($default);
33             # in case default value applied, skip validation for default value
34 6         16 next;
35             } elsif ($context->prims->is_boolean($definition->{required}) && $definition->{required}) {
36             # if {required: true} specified and default not exists, it's invalid(draftv3).
37             # if {required: [properties]} specified, just skip it(draftv4).
38             # TODO check definition. Is it valid existing "default" and "required" in same property???
39 5         82 $is_valid=0;
40 5         12 last;
41             } else {
42 68         215 next; # skip on no-required empty
43             }
44             }
45              
46 186         319 my $sub_data = $data->{$prop};
47 186         308 my $sub_schema = $properties->{$prop};
48             my $res = $context->in($prop, sub {
49 186         480 $context->sub_validator($sub_schema)->validate($sub_data, $context);
50 186         774 });
51              
52 184 100       721 if (!$res) {
53 43         81 $is_valid = 0;
54 43         88 last;
55             }
56             }
57              
58 179         485 $is_valid;
59 189         1145 });
60             }
61              
62             1;