File Coverage

blib/lib/Valiemon/Attributes/AdditionalItems.pm
Criterion Covered Total %
statement 41 43 95.3
branch 12 14 85.7
condition 2 3 66.6
subroutine 11 11 100.0
pod 0 2 0.0
total 66 73 90.4


line stmt bran cond sub pod time code
1             package Valiemon::Attributes::AdditionalItems;
2 2     2   1226 use strict;
  2         6  
  2         57  
3 2     2   10 use warnings;
  2         4  
  2         46  
4 2     2   10 use utf8;
  2         4  
  2         26  
5 2     2   482 use parent qw(Valiemon::Attributes);
  2         321  
  2         9  
6              
7 2     2   125 use Carp qw(croak);
  2         4  
  2         107  
8 2     2   17 use List::MoreUtils qw(all);
  2         4  
  2         15  
9 2     2   1389 use Valiemon;
  2         4  
  2         698  
10              
11 8     8 0 25 sub attr_name { 'additionalItems' }
12              
13             sub is_valid {
14 14     14 0 36 my ($class, $context, $schema, $data) = @_;
15 14 100       41 return 1 unless ref $data eq 'ARRAY'; # ignore
16              
17 12         22 my $items = $schema->{items};
18 12         19 my $additionalItems = $schema->{additionalItems};
19              
20             # `additionalItems` works only when `items` is present and its type is array
21 12 100       34 return 1 unless ref $items eq 'ARRAY';
22              
23 8 100       25 if (ref $additionalItems eq 'HASH') {
    50          
24             # schema
25             return $context->in_attr($class, sub {
26 4     4   21 my $idx = 0;
27 4         59 my $n = scalar @$items;
28 4         13 my $sub_v = $context->sub_validator($additionalItems);
29             all {
30             # Initial n items are validated by `items`
31 16 100       39 if ($idx >= $n) {
32 14         53 $context->in($idx, sub { $sub_v->validate($_, $context) });
  14         39  
33             }
34 16         54 $idx += 1;
35 4         39 } @$data;
36 4         25 });
37             } elsif (ref $additionalItems eq 'ARRAY') {
38 0         0 croak sprintf '`additionalItems` must be an object or boolean value at %s.',
39             $context->position;
40             } else {
41             # boolean
42             return $context->in_attr($class, sub {
43 4 50   4   12 if (!$context->prims->is_boolean($additionalItems)) {
44 0         0 croak sprintf '`additionalItems` must be an object or boolean value at %s.',
45             $context->position;
46             }
47 4 100 66     51 return 0 if !$additionalItems && (scalar @$data > scalar @$items);
48 2         25 return 1;
49 4         22 });
50             }
51             }
52              
53             1;