File Coverage

blib/lib/OpenAPI/Render.pm
Criterion Covered Total %
statement 58 64 90.6
branch 16 20 80.0
condition 5 9 55.5
subroutine 11 17 64.7
pod 0 15 0.0
total 90 125 72.0


line stmt bran cond sub pod time code
1             package OpenAPI::Render;
2              
3 1     1   472 use strict;
  1         2  
  1         29  
4 1     1   5 use warnings;
  1         2  
  1         975  
5              
6             # ABSTRACT: Render OpenAPI specifications as documents
7             our $VERSION = '0.2.0'; # VERSION
8              
9             sub new
10             {
11 1     1 0 617 my( $class, $api ) = @_;
12              
13 1         5 my $self = { api => dereference( $api, $api ) };
14              
15 1         2 my( $base_url ) = map { $_->{url} } @{$api->{servers} };
  1         4  
  1         3  
16 1 50       5 $self->{base_url} = $base_url if $base_url;
17              
18 1         4 return bless $self, $class;
19             }
20              
21             sub show
22             {
23 1     1 0 52 my( $self ) = @_;
24              
25 1         5 my $html = $self->header;
26              
27 1         7666 my $api = $self->{api};
28              
29 1         3 for my $path (sort keys %{$api->{paths}}) {
  1         9  
30 3         282 $html .= $self->path_header( $path );
31 3         124 for my $operation ('get', 'post', 'patch', 'put', 'delete') {
32 15 100       2107 next if !$api->{paths}{$path}{$operation};
33             my @parameters = (
34             exists $api->{paths}{$path}{parameters}
35 10         46 ? @{$api->{paths}{$path}{parameters}} : (),
36             exists $api->{paths}{$path}{$operation}{parameters}
37 2         11 ? @{$api->{paths}{$path}{$operation}{parameters}} : (),
38             exists $api->{paths}{$path}{$operation}{requestBody}
39 10 50       29 ? RequestBody2Parameters( $api->{paths}{$path}{$operation}{requestBody} ) : (),
    100          
    100          
40             );
41 10         29 my $responses = $api->{paths}{$path}{$operation}{responses};
42              
43             $html .= $self->operation_header( $path, $operation ) .
44              
45             $self->parameters_header .
46 74         176 join( '', map { $self->parameter( $_ ) } @parameters ) .
47             $self->parameters_footer .
48              
49             $self->responses_header .
50 10         28 join( '', map { $self->response( $_, $responses->{$_} ) }
  20         44  
51             sort keys %$responses ) .
52             $self->responses_footer .
53              
54             $self->operation_footer( $path, $operation );
55             }
56             }
57              
58 1         5 $html .= $self->footer;
59 1         70 return $html;
60             }
61              
62 0     0 0 0 sub header { return '' }
63 0     0 0 0 sub footer { return '' }
64 0     0 0 0 sub path_header { return '' }
65 0     0 0 0 sub operation_header { return '' }
66              
67 10     10 0 3399 sub parameters_header { return '' };
68 0     0 0 0 sub parameter { return '' }
69 10     10 0 31 sub parameters_footer { return '' };
70              
71 10     10 0 48 sub responses_header { return '' };
72 20     20 0 57 sub response { return '' };
73 10     10 0 30 sub responses_footer { return '' };
74              
75 0     0 0 0 sub operation_footer { return '' }
76              
77             sub dereference
78             {
79 307     307 0 481 my( $node, $root ) = @_;
80              
81 307 100       672 if( ref $node eq 'ARRAY' ) {
    100          
82 11         16 @$node = map { dereference( $_, $root ) } @$node;
  43         82  
83             } elsif( ref $node eq 'HASH' ) {
84 162         355 my @keys = keys %$node;
85 162 100 100     388 if( scalar @keys == 1 && $keys[0] eq '$ref' ) {
86 37         101 my @path = split '/', $node->{'$ref'};
87 37         51 shift @path;
88 37         52 $node = $root;
89 37         64 while( @path ) {
90 111         232 $node = $node->{shift @path};
91             }
92             } else {
93 125         168 %$node = map { $_ => dereference( $node->{$_}, $root ) } @keys;
  263         404  
94             }
95             }
96 307         710 return $node;
97             }
98              
99             sub RequestBody2Parameters
100             {
101 6     6 0 13 my( $requestBody ) = @_;
102              
103             return if !exists $requestBody->{content} ||
104             !exists $requestBody->{content}{'multipart/form-data'} ||
105 6 50 33     36 !exists $requestBody->{content}{'multipart/form-data'}{schema};
      33        
106              
107 6         11 my $schema = $requestBody->{content}{'multipart/form-data'}{schema};
108              
109 6 50       15 return if $schema->{type} ne 'object';
110             return ( map { {
111             in => 'query',
112             name => $_,
113 36         95 schema => $schema->{properties}{$_} } }
114 6         31 sort keys %{$schema->{properties}} ),
115             ( map { {
116             in => 'query',
117             name => $_,
118 6         36 schema => $schema->{patternProperties}{$_},
119             'x-is-pattern' => 1 } }
120 6         10 sort keys %{$schema->{patternProperties}} );
  6         14  
121             }
122              
123             1;