• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

onmoon / openapi-server-bundle / 15881876638

25 Jun 2025 04:28PM UTC coverage: 80.585% (-0.5%) from 81.095%
15881876638

Pull #196

github

web-flow
Merge 90ce8070d into c35fba5f2
Pull Request #196: Fix minimum versions install

9 of 29 new or added lines in 5 files covered. (31.03%)

44 existing lines in 12 files now uncovered.

1378 of 1710 relevant lines covered (80.58%)

3.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.79
/src/CodeGenerator/GraphGenerator.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace OnMoon\OpenApiServerBundle\CodeGenerator;
6

7
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\ComponentDefinition;
8
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\ComponentReference;
9
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\DtoDefinition;
10
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\DtoReference;
11
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\GraphDefinition;
12
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\OperationDefinition;
13
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\PropertyDefinition;
14
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\RequestHandlerInterfaceDefinition;
15
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\ResponseDefinition;
16
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\ServiceSubscriberDefinition;
17
use OnMoon\OpenApiServerBundle\CodeGenerator\Definitions\SpecificationDefinition;
18
use OnMoon\OpenApiServerBundle\Exception\CannotParseOpenApi;
19
use OnMoon\OpenApiServerBundle\Specification\Definitions\ObjectReference;
20
use OnMoon\OpenApiServerBundle\Specification\Definitions\ObjectSchema;
21
use OnMoon\OpenApiServerBundle\Specification\Definitions\Operation;
22
use OnMoon\OpenApiServerBundle\Specification\Definitions\Property;
23
use OnMoon\OpenApiServerBundle\Specification\SpecificationLoader;
24

25
use function array_map;
26
use function count;
27

28
/** @psalm-suppress ClassMustBeFinal */
29
class GraphGenerator
30
{
31
    private SpecificationLoader $loader;
32

33
    public function __construct(SpecificationLoader $loader)
34
    {
35
        $this->loader = $loader;
3✔
36
    }
37

38
    public function generateClassGraph(): GraphDefinition
39
    {
40
        $specificationDefinitions = [];
3✔
41
        foreach ($this->loader->list() as $specificationName => $specificationConfig) {
3✔
42
            $parsedSpecification = $this->loader->load($specificationName);
3✔
43

44
            $componentDefinitions = [];
3✔
45
            $componentSchemas     = $parsedSpecification->getComponentSchemas();
3✔
46
            foreach ($componentSchemas as $name => $_objectSchema) {
3✔
UNCOV
47
                $componentDefinitions[] = new ComponentDefinition($name);
×
48
            }
49

50
            foreach ($componentDefinitions as $component) {
3✔
UNCOV
51
                $component->setDto($this->objectSchemaToDefinition($componentSchemas[$component->getName()], $componentDefinitions));
×
52
            }
53

54
            $operationDefinitions = [];
3✔
55

56
            foreach ($parsedSpecification->getOperations() as $operationId => $operation) {
3✔
57
                $requestDefinition = $this->getRequestDefinition($operation, $componentDefinitions);
3✔
58

59
                $singleHttpCode = null;
3✔
60
                $responses      = $this->getResponseDefinitions($operation->getResponses(), $componentDefinitions);
3✔
61
                if (count($responses) === 1 && $responses[0]->getResponseBody()->isEmpty()) {
3✔
62
                    $singleHttpCode = $responses[0]->getStatusCode();
1✔
63
                    $responses      = [];
1✔
64
                }
65

66
                $service = new RequestHandlerInterfaceDefinition(
3✔
67
                    $requestDefinition,
3✔
68
                    array_map(
3✔
69
                        static fn (ResponseDefinition $response) => $response->getResponseBody(),
3✔
70
                        $responses
3✔
71
                    )
3✔
72
                );
3✔
73

74
                $operationDefinitions[] = new OperationDefinition(
3✔
75
                    $operation->getUrl(),
3✔
76
                    $operation->getMethod(),
3✔
77
                    $operationId,
3✔
78
                    $operation->getRequestHandlerName(),
3✔
79
                    $operation->getSummary(),
3✔
80
                    $singleHttpCode,
3✔
81
                    $requestDefinition,
3✔
82
                    $responses,
3✔
83
                    $service
3✔
84
                );
3✔
85
            }
86

87
            $specificationDefinitions[] = new SpecificationDefinition($specificationConfig, $operationDefinitions, $componentDefinitions);
3✔
88
        }
89

90
        $serviceSubscriber = new ServiceSubscriberDefinition();
3✔
91

92
        return new GraphDefinition($specificationDefinitions, $serviceSubscriber);
3✔
93
    }
94

95
    /** @param ComponentDefinition[] $components */
96
    private function getRequestDefinition(Operation $operation, array $components): ?DtoDefinition
97
    {
98
        $fields = [
3✔
99
            'pathParameters' => $operation->getRequestParameters()['path'] ?? null,
3✔
100
            'queryParameters' => $operation->getRequestParameters()['query'] ?? null,
3✔
101
            'body' => $operation->getRequestBody(),
3✔
102
        ];
3✔
103

104
        $properties = [];
3✔
105

106
        foreach ($fields as $name => $definition) {
3✔
107
            if ($definition === null) {
3✔
108
                continue;
3✔
109
            }
110

111
            $specProperty = (new Property($name))->setRequired(true);
3✔
112
            $properties[] = (new PropertyDefinition($specProperty))
3✔
113
                ->setObjectTypeDefinition($this->objectTypeToDefinition($definition, $components));
3✔
114
        }
115

116
        if (count($properties) === 0) {
3✔
UNCOV
117
            return null;
×
118
        }
119

120
        return new DtoDefinition($properties);
3✔
121
    }
122

123
    /**
124
     * @param array<string|int,ObjectSchema|ObjectReference> $responses
125
     * @param ComponentDefinition[]                          $components
126
     *
127
     * @return ResponseDefinition[]
128
     */
129
    private function getResponseDefinitions(array $responses, array $components): array
130
    {
131
        $responseDtoDefinitions = [];
3✔
132

133
        foreach ($responses as $statusCode => $response) {
3✔
134
            $responseDtoDefinitions[] = new ResponseDefinition(
3✔
135
                (string) $statusCode,
3✔
136
                $this->objectTypeToDefinition($response, $components)
3✔
137
            );
3✔
138
        }
139

140
        return $responseDtoDefinitions;
3✔
141
    }
142

143
    /** @param ComponentDefinition[] $components */
144
    private function objectTypeToDefinition(ObjectSchema|ObjectReference $type, array $components): DtoReference
145
    {
146
        if ($type instanceof ObjectReference) {
3✔
UNCOV
147
            foreach ($components as $component) {
×
148
                if ($component->getName() === $type->getSchemaName()) {
×
149
                    return new ComponentReference($component);
×
150
                }
151
            }
152

UNCOV
153
            throw CannotParseOpenApi::becauseUnknownReferenceFound($type->getSchemaName());
×
154
        }
155

156
        return $this->objectSchemaToDefinition($type, $components);
3✔
157
    }
158

159
    /** @param ComponentDefinition[] $components */
160
    private function objectSchemaToDefinition(ObjectSchema $type, array $components): DtoDefinition
161
    {
162
        return new DtoDefinition(array_map(
3✔
163
            fn (Property $p): PropertyDefinition => $this->propertyToDefinition($p, $components),
3✔
164
            $type->getProperties()
3✔
165
        ));
3✔
166
    }
167

168
    /** @param ComponentDefinition[] $components */
169
    private function propertyToDefinition(Property $property, array $components): PropertyDefinition
170
    {
171
        $definition = new PropertyDefinition($property);
3✔
172
        $objectType = $property->getObjectTypeDefinition();
3✔
173
        if ($objectType !== null) {
3✔
174
            $definition->setObjectTypeDefinition($this->objectTypeToDefinition($objectType, $components));
2✔
175
        }
176

177
        return $definition;
3✔
178
    }
179
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc