Skip to content

Commit 9447c1f

Browse files
authored
Allow to pass Context into Serializer (#1968)
1 parent 380227f commit 9447c1f

2 files changed

Lines changed: 112 additions & 85 deletions

File tree

src/Serializer.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,21 @@ protected static function isValidAnnotationClass(string $className): bool
7474
*
7575
* @param class-string<OA\AbstractAnnotation> $className
7676
*/
77-
public function deserialize(string $jsonString, string $className): OA\AbstractAnnotation
77+
public function deserialize(string $jsonString, string $className, ?Context $context = null): OA\AbstractAnnotation
7878
{
7979
if (!static::isValidAnnotationClass($className)) {
8080
throw new OpenApiException($className . ' is not defined in OpenApi PHP Annotations');
8181
}
8282

83-
return $this->doDeserialize(json_decode($jsonString), $className, new Context(['generated' => true]));
83+
return $this->doDeserialize(json_decode($jsonString), $className, $context ?? new Context(['generated' => true]));
8484
}
8585

8686
/**
8787
* Deserialize a file.
8888
*
8989
* @param class-string<OA\AbstractAnnotation> $className
9090
*/
91-
public function deserializeFile(string $filename, string $format = 'json', string $className = OA\OpenApi::class): OA\AbstractAnnotation
91+
public function deserializeFile(string $filename, string $format = 'json', string $className = OA\OpenApi::class, ?Context $context = null): OA\AbstractAnnotation
9292
{
9393
if (!static::isValidAnnotationClass($className)) {
9494
throw new OpenApiException($className . ' is not a valid OpenApi PHP Annotations');
@@ -101,7 +101,7 @@ public function deserializeFile(string $filename, string $format = 'json', strin
101101
$contents = json_encode(Yaml::parse($contents));
102102
}
103103

104-
return $this->doDeserialize(json_decode($contents), $className, new Context(['generated' => true]));
104+
return $this->doDeserialize(json_decode($contents), $className, $context ?? new Context(['generated' => true]));
105105
}
106106

107107
/**

tests/SerializerTest.php

Lines changed: 108 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use OpenApi\Annotations as OA;
1010
use OpenApi\Annotations\OpenApi;
11+
use OpenApi\Context;
1112
use OpenApi\Generator;
1213
use OpenApi\Serializer;
1314
use OpenApi\Tests\Concerns\UsesExamples;
@@ -17,7 +18,7 @@ final class SerializerTest extends OpenApiTestCase
1718
{
1819
use UsesExamples;
1920

20-
private function getExpected(): OpenApi
21+
private function getPetstoreExpected(): OpenApi
2122
{
2223
$path = new OA\PathItem(['_context' => $this->getContext()]);
2324
$path->path = '/products';
@@ -54,7 +55,7 @@ private function getExpected(): OpenApi
5455
$path->post->responses = [$resp, $respRange];
5556

5657
$expected = new OpenApi(['_context' => $this->getContext()]);
57-
$expected->openapi = OpenApi::VERSION_3_0_0;
58+
$expected->openapi = OpenApi::VERSION_3_1_0;
5859
$expected->paths = [
5960
$path,
6061
];
@@ -74,76 +75,76 @@ private function getExpected(): OpenApi
7475
return $expected;
7576
}
7677

77-
public function testDeserializeAnnotation(): void
78+
public function testDeserializePetstore(): void
7879
{
79-
$serializer = new Serializer();
80-
8180
$json = <<<JSON
8281
{
83-
"openapi": "3.0.0",
84-
"info": {
85-
"title": "Pet store",
86-
"version": "1.0"
87-
},
88-
"paths": {
89-
"/products": {
90-
"post": {
91-
"tags": [
92-
"products"
93-
],
94-
"summary": "s1",
95-
"description": "d1",
96-
"requestBody": {
97-
"description": "data in body",
98-
"content": {
99-
"application/json": {
100-
"schema": {
101-
"type": "object",
102-
"additionalProperties": true
103-
}
104-
}
105-
},
106-
"x-repository": "def"
107-
},
108-
"responses": {
109-
"200": {
110-
"description": "Success",
111-
"content": {
112-
"application/json": {
113-
"schema": {
114-
"\$ref": "#/components/schemas/Pet"
115-
}
116-
}
117-
},
118-
"x-repository": "def"
119-
},
120-
"4XX": {
121-
"description": "Client error response"
122-
}
123-
}
124-
}
125-
}
126-
},
127-
"components": {
128-
"schemas": {
129-
"Pet": {
130-
"required": [
131-
"name",
132-
"photoUrls"
133-
]
134-
}
135-
}
136-
}
82+
"openapi": "3.1.0",
83+
"info": {
84+
"title": "Pet store",
85+
"version": "1.0"
86+
},
87+
"paths": {
88+
"/products": {
89+
"post": {
90+
"tags": [
91+
"products"
92+
],
93+
"summary": "s1",
94+
"description": "d1",
95+
"requestBody": {
96+
"description": "data in body",
97+
"content": {
98+
"application/json": {
99+
"schema": {
100+
"type": "object",
101+
"additionalProperties": true
102+
}
103+
}
104+
},
105+
"x-repository": "def"
106+
},
107+
"responses": {
108+
"200": {
109+
"description": "Success",
110+
"content": {
111+
"application/json": {
112+
"schema": {
113+
"\$ref": "#/components/schemas/Pet"
114+
}
115+
}
116+
},
117+
"x-repository": "def"
118+
},
119+
"4XX": {
120+
"description": "Client error response"
121+
}
122+
}
123+
}
124+
}
125+
},
126+
"components": {
127+
"schemas": {
128+
"Pet": {
129+
"required": [
130+
"name",
131+
"photoUrls"
132+
]
133+
}
134+
}
135+
}
137136
}
138137
JSON;
139138

139+
$serializer = new Serializer();
140+
140141
/** @var OpenApi $annotation */
141142
$annotation = $serializer->deserialize($json, OpenApi::class);
142143

143144
$this->assertInstanceOf(OpenApi::class, $annotation);
144145
$this->assertJsonStringEqualsJsonString(
145146
$annotation->toJson(),
146-
$this->getExpected()->toJson()
147+
$this->getPetstoreExpected()->toJson()
147148
);
148149

149150
$schema = $annotation->paths['/products']->post->requestBody->content['application/json']->schema;
@@ -153,7 +154,7 @@ public function testDeserializeAnnotation(): void
153154
public function testPetstoreExample(): void
154155
{
155156
$serializer = new Serializer();
156-
$spec = self::examplePath('petstore/petstore-3.0.0.yaml');
157+
$spec = self::examplePath('petstore/petstore-3.1.0.yaml');
157158
$openapi = $serializer->deserializeFile($spec, 'yaml');
158159
$this->assertInstanceOf(OpenApi::class, $openapi);
159160
$this->assertSpecEquals(file_get_contents($spec), $openapi->toYaml());
@@ -166,30 +167,32 @@ public function testPetstoreExample(): void
166167
*/
167168
public function testDeserializeAllOfProperty(): void
168169
{
169-
$serializer = new Serializer();
170170
$json = <<<JSON
171171
{
172-
"openapi": "3.0.0",
173-
"info": {
174-
"title": "Pet store",
175-
"version": "1.0"
176-
},
177-
"components": {
178-
"schemas": {
179-
"Dog": {
180-
"allOf": [{
181-
"\$ref": "#/components/schemas/SomeSchema"
182-
}]
183-
},
184-
"Cat": {
185-
"allOf": [{
186-
"\$ref": "#/components/schemas/SomeSchema"
187-
}]
188-
}
189-
}
190-
}
172+
"openapi": "3.0.0",
173+
"info": {
174+
"title": "Pet store",
175+
"version": "1.0"
176+
},
177+
"components": {
178+
"schemas": {
179+
"Dog": {
180+
"allOf": [{
181+
"\$ref": "#/components/schemas/SomeSchema"
182+
}]
183+
},
184+
"Cat": {
185+
"allOf": [{
186+
"\$ref": "#/components/schemas/SomeSchema"
187+
}]
188+
}
189+
}
190+
}
191191
}
192192
JSON;
193+
194+
$serializer = new Serializer();
195+
193196
/** @var OpenApi $annotation */
194197
$annotation = $serializer->deserialize($json, OpenApi::class);
195198

@@ -212,4 +215,28 @@ public function testValidAnnotationsListComplete(string $annotation): void
212215
$staticProperties = (new \ReflectionClass((Serializer::class)))->getStaticProperties();
213216
$this->assertArrayHasKey($annotation, array_flip($staticProperties['VALID_ANNOTATIONS']));
214217
}
218+
219+
public function testSerializeWithContext(): void
220+
{
221+
$json = <<<JSON
222+
{
223+
"tags": [
224+
{
225+
"name": "Foo",
226+
"summary": "Foo stuff"
227+
}
228+
]
229+
}
230+
JSON;
231+
232+
$serializer = new Serializer();
233+
234+
/** @var OpenApi $annotation */
235+
$annotation = $serializer->deserialize($json, OpenApi::class, new Context(['version' => '3.2.0', 'generated' => true]));
236+
237+
$this->assertJsonStringEqualsJsonString(
238+
str_replace('"tags"', '"openapi":"3.2.0", "tags"', $json),
239+
$annotation->toJson(),
240+
);
241+
}
215242
}

0 commit comments

Comments
 (0)