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   444 use strict;
  1         2  
  1         30  
4 1     1   4 use warnings;
  1         2  
  1         910  
5              
6             # ABSTRACT: Render OpenAPI specifications as documents
7             our $VERSION = '0.1.0'; # VERSION
8              
9             sub new
10             {
11 1     1 0 600 my( $class, $api ) = @_;
12              
13 1         4 my $self = { api => dereference( $api, $api ) };
14              
15 1         2 my( $base_url ) = map { $_->{url} } @{$api->{servers} };
  1         3  
  1         3  
16 1 50       5 $self->{base_url} = $base_url if $base_url;
17              
18 1         5 return bless $self, $class;
19             }
20              
21             sub show
22             {
23 1     1 0 47 my( $self ) = @_;
24              
25 1         5 my $html = $self->header;
26              
27 1         7093 my $api = $self->{api};
28              
29 1         2 for my $path (sort keys %{$api->{paths}}) {
  1         7  
30 3         321 $html .= $self->path_header( $path );
31 3         108 for my $operation ('get', 'post', 'patch', 'put', 'delete') {
32 15 100       2029 next if !$api->{paths}{$path}{$operation};
33             my @parameters = (
34             exists $api->{paths}{$path}{parameters}
35 10         45 ? @{$api->{paths}{$path}{parameters}} : (),
36             exists $api->{paths}{$path}{$operation}{parameters}
37 2         8 ? @{$api->{paths}{$path}{$operation}{parameters}} : (),
38             exists $api->{paths}{$path}{$operation}{requestBody}
39 10 50       26 ? RequestBody2Parameters( $api->{paths}{$path}{$operation}{requestBody} ) : (),
    100          
    100          
40             );
41 10         24 my $responses = $api->{paths}{$path}{$operation}{responses};
42              
43             $html .= $self->operation_header( $path, $operation ) .
44              
45             $self->parameters_header .
46 74         179 join( '', map { $self->parameter( $_ ) } @parameters ) .
47             $self->parameters_footer .
48              
49             $self->responses_header .
50 10         29 join( '', map { $self->response( $_, $responses->{$_} ) }
  20         42  
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         61 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 3378 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 34 sub responses_header { return '' };
72 20     20 0 47 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 474 my( $node, $root ) = @_;
80              
81 307 100       623 if( ref $node eq 'ARRAY' ) {
    100          
82 11         15 @$node = map { dereference( $_, $root ) } @$node;
  43         76  
83             } elsif( ref $node eq 'HASH' ) {
84 162         350 my @keys = keys %$node;
85 162 100 100     440 if( scalar @keys == 1 && $keys[0] eq '$ref' ) {
86 37         93 my @path = split '/', $node->{'$ref'};
87 37         44 shift @path;
88 37         61 $node = $root;
89 37         65 while( @path ) {
90 111         229 $node = $node->{shift @path};
91             }
92             } else {
93 125         179 %$node = map { $_ => dereference( $node->{$_}, $root ) } @keys;
  263         415  
94             }
95             }
96 307         718 return $node;
97             }
98              
99             sub RequestBody2Parameters
100             {
101 6     6 0 16 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         93 schema => $schema->{properties}{$_} } }
114 6         30 sort keys %{$schema->{properties}} ),
115             ( map { {
116             in => 'query',
117             name => $_,
118 6         29 schema => $schema->{patternProperties}{$_},
119             _is_pattern => 1 } }
120 6         9 sort keys %{$schema->{patternProperties}} );
  6         13  
121             }
122              
123             1;