File Coverage

lib/APISchema/Generator/Markdown/ResourceResolver.pm
Criterion Covered Total %
statement 58 67 86.5
branch 19 34 55.8
condition 10 19 52.6
subroutine 13 13 100.0
pod 0 2 0.0
total 100 135 74.0


line stmt bran cond sub pod time code
1             package APISchema::Generator::Markdown::ResourceResolver;
2 3     3   43 use 5.014;
  3         9  
3 3     3   14 use strict;
  3         4  
  3         51  
4 3     3   11 use warnings;
  3         5  
  3         107  
5              
6             # cpan
7 3     3   903 use JSON::Pointer;
  3         20032  
  3         122  
8             use Class::Accessor::Lite (
9 3         24 new => 1,
10             ro => [qw(schema)],
11 3     3   24 );
  3         6  
12              
13             sub _foreach_properties($$&) {
14 67     67   143 my ($name_path, $definition, $callback) = @_;
15 67 50 50     226 return unless (ref $definition || '') eq 'HASH';
16              
17 67 100       166 if ($definition->{items}) {
18 1         63 my $items = $definition->{items};
19 1   50     6 my $type = ref $items || '';
20 1 50       4 if ($type eq 'HASH') {
    0          
21 1         5 $callback->([@$name_path, '[]'], $items);
22             } elsif ($type eq 'ARRAY') {
23 0         0 $callback->([@$name_path, "[$_]"], $items->{$_}) for (0..$#$items);
24             }
25             }
26              
27 67 100       177 if ($definition->{properties}) {
28 42         80 my $items = $definition->{properties};
29 42   50     110 my $type = ref $items || '';
30 42 50       110 if ($type eq 'HASH') {
31 42         204 $callback->([@$name_path, $_], $items->{$_}) for keys %$items;
32             }
33             }
34             }
35              
36             sub _property_name (@) {
37 39     39   83 my @name_path = @_;
38 39         168 return '.' . join '.', @name_path;
39             }
40              
41             sub _collect_properties {
42 40     40   98 my ($self, $path, $definition) = @_;
43 40 50 50     136 return {} unless (ref $definition || '') eq 'HASH';
44              
45 40         79 my $ref = $definition->{'$ref'};
46 40 100       84 if ($ref) {
47 3         18 $ref = $ref =~ s/^#//r;
48 3         13 my $def = JSON::Pointer->get($self->schema, $ref);
49 3 100 66     662 return $self->_collect_properties($path, $def)
50             if $def && $ref !~ qr!^/resource/[^/]+$!;
51              
52             $definition = +{
53             %$definition,
54             description => $definition->{description} // $def->{description},
55 2   66     51 };
56             }
57              
58 39         94 my $result = { _property_name(@$path) => $definition };
59             _foreach_properties($path, $definition, sub {
60             $result = +{
61             %$result,
62 21     21   56 %{$self->_collect_properties(@_)},
  21         57  
63             };
64 39         218 });
65 39         237 return $result;
66             }
67              
68             sub _collect_example {
69 96     96   195 my ($self, $path, $definition) = @_;
70 96 100       308 return $definition->{example} if defined $definition->{example};
71              
72 47         89 my $ref = $definition->{'$ref'};
73 47 100       107 if ($ref) {
74 19         90 $ref = $ref =~ s/^#//r;
75 19         66 my $def = JSON::Pointer->get($self->schema, $ref);
76 19 50       3837 return $self->_collect_example($path, $def) if $def;
77             }
78              
79 28         45 my %result;
80 28   50     76 my $type = $definition->{type} || '';
81             _foreach_properties($path, $definition, sub {
82 41   33 41   116 my $example = $self->_collect_example(@_) // $_[1]->{default};
83 41 50       200 $result{$_[0]->[-1]} = $example if defined $example;
84 28         168 });
85              
86 28 50       221 return \%result if $type eq 'object';
87              
88 0 0       0 if ($type eq 'array') {
89 0 0       0 return [ $result{'[]'} ] if $result{'[]'};
90              
91 0         0 my @result;
92 0         0 for (keys %result) {
93 0 0       0 next unless $_ =~ /\A\[([0-9]+)\]\z/;
94 0         0 $result[$1] = $result{$_};
95             }
96 0         0 return \@result;
97             }
98              
99 0         0 return undef;
100             }
101              
102             sub properties {
103 18     18 0 111 my ($self, $resource) = @_;
104 18         64 return $self->_collect_properties([], $resource);
105             }
106              
107             sub example {
108 36     36 0 385 my ($self, $resource) = @_;
109 36         118 return $self->_collect_example([], $resource);
110             }
111              
112             1;