File Coverage

blib/lib/Valiemon/Attributes/Dependencies.pm
Criterion Covered Total %
statement 48 53 90.5
branch 20 26 76.9
condition n/a
subroutine 11 11 100.0
pod 0 3 0.0
total 79 93 84.9


line stmt bran cond sub pod time code
1             package Valiemon::Attributes::Dependencies;
2 2     2   826 use strict;
  2         4  
  2         48  
3 2     2   6 use warnings;
  2         1  
  2         36  
4 2     2   5 use utf8;
  2         2  
  2         6  
5 2     2   34 use parent qw(Valiemon::Attributes);
  2         7  
  2         7  
6              
7 2     2   87 use Carp qw(croak);
  2         6  
  2         78  
8 2     2   6 use List::MoreUtils qw(all any);
  2         6  
  2         16  
9              
10 27     27 0 96 sub attr_name { 'dependencies' }
11              
12             sub is_valid {
13 27     27 0 32 my ($class, $context, $schema, $data) = @_;
14             $context->in_attr($class, sub {
15 27 100   27   63 return 1 unless ref $data eq 'HASH'; # ignore
16              
17 26         26 my $dependencies = $schema->{dependencies};
18 26 50       34 unless (ref $dependencies eq 'HASH') {
19 0         0 croak sprintf '`dependencies` must be an object at %s', $context->position
20             }
21              
22 26         50 for my $name (keys %$dependencies) {
23 26         18 my $subschema_or_propertyset = $dependencies->{$name};
24              
25 26 100       53 if (ref $subschema_or_propertyset eq 'HASH') {
    100          
    50          
26             # schema dependencies
27 9         16 my $sub_v = $context->sub_validator($subschema_or_propertyset);
28 9 100       19 next unless exists $data->{$name};
29 8 100       16 next if $sub_v->validate($data);
30 6         16 return 0;
31             } elsif (ref $subschema_or_propertyset eq 'ARRAY') {
32             # property dependencies
33 16 50       31 unless ( scalar @$subschema_or_propertyset > 0 ) {
34 0         0 croak sprintf 'In case value of `dependencies` is an array, it must have at least one element at %s', $context->position;
35             }
36             # assume all values are string
37 16 50       50 unless ( all { $context->prims->is_string($_) } @$subschema_or_propertyset ) {
  28         49  
38 0         0 croak sprintf 'All elements of value of `dependencies` must be a string at %s', $context->position;
39             }
40             # assume are values are unique
41 16 50       45 unless ( $class->check_all_uniqueness($context, $subschema_or_propertyset) ) {
42 0         0 croak sprintf 'All elements of value of `dependencies` must be unique at %s', $context->position;
43             }
44 16 100       76 next unless exists $data->{$name};
45 10 100       32 next if all { exists $data->{$_} } @$subschema_or_propertyset;
  14         27  
46 7         17 return 0;
47             } elsif ( $context->prims->is_string($subschema_or_propertyset) ) {
48             # In draft 3, string was allowed (as a singly value of propertyset)
49 1         3 croak sprintf '`dependencies` member values can no longer be single strings at %s', $context->position;
50             } else {
51 0         0 croak sprintf 'Invalid value of `dependencies` at %s', $context->position;
52             }
53             }
54 12         22 return 1;
55 27         136 });
56             }
57              
58             sub check_all_uniqueness {
59 16     16 0 18 my ($class, $context, $elements) = @_;
60              
61 16         17 my $unique_elements = [];
62 16         20 for my $elem (@$elements) {
63 28 50   12   78 return 0 if any { $context->prims->is_equal($_, $elem) } @$unique_elements;
  12         18  
64 28         71 push @$unique_elements, $elem;
65             }
66 16         40 return 1;
67             }
68              
69             1;