File Coverage

lib/APISchema/Generator/Markdown/ResourceResolver.pm
Criterion Covered Total %
statement 62 74 83.7
branch 22 40 55.0
condition 10 19 52.6
subroutine 13 13 100.0
pod 0 2 0.0
total 107 148 72.3


line stmt bran cond sub pod time code
1             package APISchema::Generator::Markdown::ResourceResolver;
2 3     3   47 use 5.014;
  3         8  
3 3     3   14 use strict;
  3         4  
  3         61  
4 3     3   14 use warnings;
  3         4  
  3         73  
5              
6             # cpan
7 3     3   1405 use JSON::Pointer;
  3         24305  
  3         112  
8             use Class::Accessor::Lite (
9 3         19 new => 1,
10             ro => [qw(schema)],
11 3     3   22 );
  3         4  
12              
13             sub _foreach_properties($$&) {
14 74     74   137 my ($name_path, $definition, $callback) = @_;
15 74 50 50     205 return unless (ref $definition || '') eq 'HASH';
16              
17 74 100       147 if ($definition->{items}) {
18 1         2 my $items = $definition->{items};
19 1   50     5 my $type = ref $items || '';
20 1 50       3 if ($type eq 'HASH') {
    0          
21 1         4 $callback->([@$name_path, '[]'], $items);
22             } elsif ($type eq 'ARRAY') {
23 0         0 $callback->([@$name_path, "[$_]"], $items->{$_}) for (0..$#$items);
24             }
25             }
26              
27 74 100       154 if ($definition->{properties}) {
28 48         66 my $items = $definition->{properties};
29 48   50     110 my $type = ref $items || '';
30 48 50       97 if ($type eq 'HASH') {
31 48         206 $callback->([@$name_path, $_], $items->{$_}) for keys %$items;
32             }
33             }
34             }
35              
36             sub _property_name (@) {
37 41     41   76 my @name_path = @_;
38 41         155 return '.' . join '.', @name_path;
39             }
40              
41             sub _collect_properties {
42 42     42   83 my ($self, $path, $definition) = @_;
43 42 50 50     118 return {} unless (ref $definition || '') eq 'HASH';
44              
45 42         71 my $ref = $definition->{'$ref'};
46 42 100       91 if ($ref) {
47 3         14 $ref = $ref =~ s/^#//r;
48 3         9 my $def = JSON::Pointer->get($self->schema, $ref);
49 3 100 66     563 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     20 };
56             }
57              
58 41         87 my $result = { _property_name(@$path) => $definition };
59             _foreach_properties($path, $definition, sub {
60             $result = +{
61             %$result,
62 22     22   52 %{$self->_collect_properties(@_)},
  22         47  
63             };
64 41         212 });
65 41         224 return $result;
66             }
67              
68             sub _collect_example {
69 113     113   186 my ($self, $path, $definition) = @_;
70 113 100       301 return ($definition->{example}, 1) if exists $definition->{example};
71              
72 59 100 33     310 if (my $union = $definition->{oneOf} || $definition->{anyOf} || $definition->{allOf}) {
73 1         3 return ($self->_collect_example($path, $union->[0]), 1);
74             }
75              
76 58         86 my $ref = $definition->{'$ref'};
77 58 100       121 if ($ref) {
78 25         99 $ref = $ref =~ s/^#//r;
79 25         73 my $def = JSON::Pointer->get($self->schema, $ref);
80 25 50       4236 return ($self->_collect_example($path, $def), 1) if $def;
81             }
82              
83 33         54 my %result;
84 33   50     68 my $type = $definition->{type} || '';
85             _foreach_properties($path, $definition, sub {
86 46     46   94 my ($example, $exists) = $self->_collect_example(@_);
87 46 50       119 unless ($exists) {
88 0 0       0 if (exists $_[1]->{default}) {
89 0         0 $example = $_[1]->{default};
90 0         0 $exists = 1;
91             }
92             }
93 46 50       194 $result{$_[0]->[-1]} = $example if $exists;
94 33         181 });
95              
96 33 50       208 return (\%result, 1) if $type eq 'object';
97              
98 0 0       0 if ($type eq 'array') {
99 0 0       0 return ([ $result{'[]'} ], 1) if $result{'[]'};
100              
101 0         0 my @result;
102 0         0 for (keys %result) {
103 0 0       0 next unless $_ =~ /\A\[([0-9]+)\]\z/;
104 0         0 $result[$1] = $result{$_};
105             }
106 0         0 return (\@result, 1);
107             }
108              
109 0         0 return (undef, 0);
110             }
111              
112             sub properties {
113 19     19 0 116 my ($self, $resource) = @_;
114 19         64 return $self->_collect_properties([], $resource);
115             }
116              
117             sub example {
118 41     41 0 356 my ($self, $resource) = @_;
119 41         113 my ($example) = $self->_collect_example([], $resource);
120 41         1122 return $example;
121             }
122              
123             1;