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   1123 use strict;
  2         4  
  2         63  
3 2     2   11 use warnings;
  2         4  
  2         51  
4 2     2   11 use utf8;
  2         4  
  2         9  
5 2     2   52 use parent qw(Valiemon::Attributes);
  2         13  
  2         14  
6              
7 2     2   115 use Carp qw(croak);
  2         4  
  2         93  
8 2     2   12 use List::MoreUtils qw(all any);
  2         4  
  2         16  
9              
10 27     27 0 87 sub attr_name { 'dependencies' }
11              
12             sub is_valid {
13 27     27 0 70 my ($class, $context, $schema, $data) = @_;
14             $context->in_attr($class, sub {
15 27 100   27   85 return 1 unless ref $data eq 'HASH'; # ignore
16              
17 26         45 my $dependencies = $schema->{dependencies};
18 26 50       68 unless (ref $dependencies eq 'HASH') {
19 0         0 croak sprintf '`dependencies` must be an object at %s', $context->position
20             }
21              
22 26         64 for my $name (keys %$dependencies) {
23 26         45 my $subschema_or_propertyset = $dependencies->{$name};
24              
25 26 100       104 if (ref $subschema_or_propertyset eq 'HASH') {
    100          
    50          
26             # schema dependencies
27 9         25 my $sub_v = $context->sub_validator($subschema_or_propertyset);
28 9 100       31 next unless exists $data->{$name};
29 8 100       24 next if $sub_v->validate($data);
30 6         25 return 0;
31             } elsif (ref $subschema_or_propertyset eq 'ARRAY') {
32             # property dependencies
33 16 50       40 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       109 unless ( all { $context->prims->is_string($_) } @$subschema_or_propertyset ) {
  28         77  
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       69 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       45 next unless exists $data->{$name};
45 10 100       40 next if all { exists $data->{$_} } @$subschema_or_propertyset;
  14         40  
46 7         27 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         4 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         32 return 1;
55 27         190 });
56             }
57              
58             sub check_all_uniqueness {
59 16     16 0 35 my ($class, $context, $elements) = @_;
60              
61 16         31 my $unique_elements = [];
62 16         32 for my $elem (@$elements) {
63 28 50   12   110 return 0 if any { $context->prims->is_equal($_, $elem) } @$unique_elements;
  12         29  
64 28         109 push @$unique_elements, $elem;
65             }
66 16         51 return 1;
67             }
68              
69             1;