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   798 use strict;
  2         23  
  2         47  
3 2     2   6 use warnings;
  2         2  
  2         101  
4 2     2   7 use utf8;
  2         6  
  2         7  
5 2     2   44 use parent qw(Valiemon::Attributes);
  2         2  
  2         9  
6              
7 2     2   87 use Carp qw(croak);
  2         3  
  2         98  
8 2     2   7 use List::MoreUtils qw(all);
  2         30  
  2         10  
9 2     2   503 use Valiemon;
  2         2  
  2         458  
10              
11 8     8 0 13 sub attr_name { 'additionalItems' }
12              
13             sub is_valid {
14 14     14 0 17 my ($class, $context, $schema, $data) = @_;
15 14 100       27 return 1 unless ref $data eq 'ARRAY'; # ignore
16              
17 12         12 my $items = $schema->{items};
18 12         11 my $additionalItems = $schema->{additionalItems};
19              
20             # `additionalItems` works only when `items` is present and its type is array
21 12 100       20 return 1 unless ref $items eq 'ARRAY';
22              
23 8 100       19 if (ref $additionalItems eq 'HASH') {
    50          
24             # schema
25             return $context->in_attr($class, sub {
26 4     4   4 my $idx = 0;
27 4         3 my $n = scalar @$items;
28 4         9 my $sub_v = $context->sub_validator($additionalItems);
29             all {
30             # Initial n items are validated by `items`
31 16 100       25 if ($idx >= $n) {
32 14         42 $context->in($idx, sub { $sub_v->validate($_, $context) });
  14         28  
33             }
34 16         34 $idx += 1;
35 4         46 } @$data;
36 4         18 });
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   10 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     42 return 0 if !$additionalItems && (scalar @$data > scalar @$items);
48 2         17 return 1;
49 4         17 });
50             }
51             }
52              
53             1;