Skip to content

Commit 8769bd2

Browse files
committed
Cleaned up using data providers
1 parent 30ce728 commit 8769bd2

1 file changed

Lines changed: 136 additions & 47 deletions

File tree

tests/Unit/AnnotationGeneratorTest.php

Lines changed: 136 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,21 @@ class AnnotationGeneratorTest extends TestCase
154154
* @throws Exception
155155
*/';
156156

157+
/**
158+
* @var array
159+
*/
160+
private static $normalisedExamples;
161+
162+
/**
163+
* @var array
164+
*/
165+
private static $truncatedExamples;
166+
167+
/**
168+
* @var array
169+
*/
170+
private static $exampleSchemas;
171+
157172
/**
158173
* @var AnnotationGenerator
159174
*/
@@ -171,7 +186,7 @@ public function setUp(): void
171186
* @return string String contents of the raw response body. If the file isn't found, an empty string is returned.
172187
* @throws \Exception
173188
*/
174-
private function getRawExampleResponseForApiEndpoint(string $apiEndpoint, string $format = 'json'): string
189+
private static function getRawExampleResponseForApiEndpoint(string $apiEndpoint, string $format = 'json'): string
175190
{
176191
if (!in_array(strtolower($format), ['json', 'xml', 'tsv'])) {
177192
throw new \Exception('Invalid format: ' . $format . '. Must be: "json", "xml", or "tsv"');
@@ -188,42 +203,65 @@ private function getRawExampleResponseForApiEndpoint(string $apiEndpoint, string
188203
* @return string String contents of the raw response body. If the file isn't found, an empty string is returned.
189204
* @throws \Exception
190205
*/
191-
private function getRawExampleResponseForPluginMethod(string $plugin, string $method, string $format = 'json'): string
206+
private static function getRawExampleResponseForPluginMethod(string $plugin, string $method, string $format = 'json'): string
192207
{
193-
return $this->getRawExampleResponseForApiEndpoint("{$plugin}.{$method}", $format);
208+
return self::getRawExampleResponseForApiEndpoint("{$plugin}.{$method}", $format);
194209
}
195210

196211
/**
197-
* Get the map of example responses. The default is returning the map for all the example responses after they've
198-
* been normalised for schema generation, but before being truncated.
212+
* Get the map of example responses which have been normalised in preparation of building schemas.
199213
*
200-
* @param bool $exampleResponseSchemas Return the generated schemas of the example responses.
201-
* @param bool $onlyExamplesThatWereTruncated Return only the example responses that were truncated.
214+
* @return array The map of example responses for a bunch of API endpoints.
215+
* E.g. ['plugin.method' => ['json' => '...', 'xml' => '...', 'tsv' => '...']]
216+
*/
217+
private static function getNormalisedExamples(): array
218+
{
219+
if (empty(self::$normalisedExamples)) {
220+
$demoExampleResponsesString = file_get_contents(self::TEST_RESOURCES_DIR . '/ExampleResponsesNormalised/ExamplesFromDemoByType.json') ?: '';
221+
$localExampleResponsesString = file_get_contents(self::TEST_RESOURCES_DIR . '/ExampleResponsesNormalised/ExamplesFromLocalByType.json') ?: '';
222+
$demoJson = json_decode($demoExampleResponsesString, true) ?? [];
223+
$localJson = json_decode($localExampleResponsesString, true) ?? [];
224+
self::$normalisedExamples = array_merge($demoJson, $localJson);
225+
}
226+
227+
return self::$normalisedExamples;
228+
}
229+
230+
/**
231+
* Get the map of example responses which have been normalised and truncated.
202232
*
203233
* @return array The map of example responses for a bunch of API endpoints.
204234
* E.g. ['plugin.method' => ['json' => '...', 'xml' => '...', 'tsv' => '...']]
205235
*/
206-
private function getExampleResponsesMap(bool $exampleResponseSchemas = false, bool $onlyExamplesThatWereTruncated = false): array
236+
private static function getTruncatedExamples(bool $onlyTruncated = false): array
207237
{
208-
if ($exampleResponseSchemas && $onlyExamplesThatWereTruncated) {
209-
throw new \Exception('Only one type of example response can be returned at a time.');
238+
if (empty(self::$truncatedExamples)) {
239+
$exampleResponsesPostTruncationString = file_get_contents(self::TEST_RESOURCES_DIR . '/ExampleResponsesNormalised/ExamplesPostTruncationByType.json') ?: '';
240+
self::$truncatedExamples = json_decode($exampleResponsesPostTruncationString, true) ?? [];
210241
}
211242

212-
if ($exampleResponseSchemas) {
213-
$exampleResponseSchemasString = file_get_contents(self::TEST_RESOURCES_DIR . '/ExampleResponsesNormalised/ExamplesSchemasByType.json') ?: '';
214-
return json_decode($exampleResponseSchemasString, true) ?? [];
243+
if ($onlyTruncated) {
244+
return self::$truncatedExamples;
215245
}
216246

217-
if ($onlyExamplesThatWereTruncated) {
218-
$exampleResponsesPostTruncationString = file_get_contents(self::TEST_RESOURCES_DIR . '/ExampleResponsesNormalised/ExamplesPostTruncationByType.json') ?: '';
219-
return json_decode($exampleResponsesPostTruncationString, true) ?? [];
247+
// Return the normalised examples with any truncated examples overriding them
248+
return array_merge(self::getNormalisedExamples(), self::$truncatedExamples);
249+
}
250+
251+
/**
252+
* Get the map of example schemas.
253+
*
254+
* @return array The map of example schemas for a bunch of API endpoints.
255+
* E.g. ['plugin.method' => ['json' => '...', 'xml' => '...', 'tsv' => '...']]
256+
*/
257+
private static function getExampleSchemas(): array
258+
{
259+
if (empty(self::$exampleSchemas)) {
260+
$exampleResponseSchemasString = file_get_contents(self::TEST_RESOURCES_DIR . '/ExampleResponsesNormalised/ExamplesSchemasByType.json') ?: '';
261+
self::$exampleSchemas = json_decode($exampleResponseSchemasString, true) ?? [];
220262
}
221263

222-
$demoExampleResponsesString = file_get_contents(self::TEST_RESOURCES_DIR . '/ExampleResponsesNormalised/ExamplesFromDemoByType.json') ?: '';
223-
$localExampleResponsesString = file_get_contents(self::TEST_RESOURCES_DIR . '/ExampleResponsesNormalised/ExamplesFromLocalByType.json') ?: '';
224-
$demoJson = json_decode($demoExampleResponsesString, true) ?? [];
225-
$localJson = json_decode($localExampleResponsesString, true) ?? [];
226-
return array_merge($demoJson, $localJson);
264+
return self::$exampleSchemas;
227265
}
228266

229267
public function testGeneratePluginApiAnnotations(): void
@@ -274,7 +312,7 @@ public function testGetResponseInfoFromDocBlock(): void
274312
{
275313
// TODO - Update to use resource file and/or dataprovider to test more than one comment block
276314
$expected = [
277-
'type' => 'array'
315+
'type' => 'array',
278316
];
279317
$this->assertEquals($expected, $this->annotationGenerator->getResponseInfoFromDocBlock(self::EXAMPLE_API_METHOD_DOC_BLOCK1));
280318
}
@@ -297,7 +335,7 @@ public function testBuildVirtualPath(string $pathTemplate, string $pluginName, s
297335
/**
298336
* @return iterable<string, string, string, string>
299337
*/
300-
public function getTestDataForBuildVirtualPath(): iterable
338+
public static function getTestDataForBuildVirtualPath(): iterable
301339
{
302340
yield 'should be empty when all values are empty' => ['', '', '', ''];
303341
yield 'should be empty when template is empty' => ['', 'SomePlugin', 'SomeMethod', ''];
@@ -729,14 +767,33 @@ public function testGetReportExampleUrlFromMetadata(): void
729767
$this->expectNotToPerformAssertions();
730768
}
731769

732-
public function testConvertExampleXmlToObject(): void
770+
/**
771+
* @dataProvider getTestXmlExampleObjectData
772+
*
773+
* @param string $endpoint
774+
* @param string $content
775+
* @param string $expected
776+
*
777+
* @return void
778+
* @throws \Exception
779+
*/
780+
public function testConvertExampleXmlToObject(string $endpoint, string $content, string $expected): void
781+
{
782+
$this->assertNotEmpty($content, 'The example response should not be empty for endpoint: ' . $endpoint);
783+
$this->assertEquals($expected, json_encode($this->annotationGenerator->convertExampleXmlToObject($content)), "The converted XML was not as expected for endpoint $endpoint.");
784+
}
785+
786+
/**
787+
* @return iterable<string, string, string>
788+
* @throws \Exception
789+
*/
790+
public static function getTestXmlExampleObjectData(): iterable
733791
{
734-
$normalisedMap = $this->getExampleResponsesMap();
792+
$normalisedMap = self::getNormalisedExamples();
735793
foreach (self::EXAMPLE_API_ENDPOINTS as $endpoint) {
736-
$content = $this->getRawExampleResponseForApiEndpoint($endpoint, 'xml');
737-
$this->assertNotEmpty($content, 'The example response should not be empty for endpoint: ' . $endpoint);
794+
$content = self::getRawExampleResponseForApiEndpoint($endpoint, 'xml');
738795
$expected = $normalisedMap[$endpoint]['xml'] ?? [];
739-
$this->assertEquals($expected, json_encode($this->annotationGenerator->convertExampleXmlToObject($content)), "The converted XML was not as expected for endpoint $endpoint.");
796+
yield "converted XML should match expected JSON for $endpoint endpoint" => [$endpoint, $content, $expected];
740797
}
741798
}
742799

@@ -746,10 +803,32 @@ public function testDetermineResponses(): void
746803
$this->expectNotToPerformAssertions();
747804
}
748805

749-
public function testCutExampleCloseToCharLimit(): void
806+
/**
807+
* @dataProvider getTestTruncatedExampleObjectData
808+
*
809+
* @param string $endpoint
810+
* @param string $type
811+
* @param string $normalisedExample
812+
* @param string $expectedExample
813+
*
814+
* @return void
815+
*/
816+
public function testCutExampleCloseToCharLimit(string $endpoint, string $type, string $normalisedExample, string $expectedExample): void
750817
{
751-
$truncatedMap = $this->getExampleResponsesMap(false, true);
752-
$normalisedMap = $this->getExampleResponsesMap();
818+
$this->assertNotEmpty($normalisedExample, "The example response should not be empty for endpoint '$endpoint' and type '$type'.");
819+
$result = $this->annotationGenerator->cutExampleCloseToCharLimit($normalisedExample, $type);
820+
// Add a little wiggle room since the truncation isn't exact and might allow a little over the limit
821+
$this->assertLessThanOrEqual(AnnotationGenerator::EXAMPLE_CHAR_LIMIT + 30, strlen($result), "The example response should not exceed the character limit for endpoint '$endpoint' and type '$type'.");
822+
$this->assertEquals($expectedExample, $result, "The truncated example was not as expected for endpoint '$endpoint' and type '$type'.");
823+
}
824+
825+
/**
826+
* @return iterable<string, string, string, string>
827+
*/
828+
public static function getTestTruncatedExampleObjectData(): iterable
829+
{
830+
$truncatedMap = self::getTruncatedExamples();
831+
$normalisedMap = self::getNormalisedExamples();
753832
foreach (self::EXAMPLE_API_ENDPOINTS as $endpoint) {
754833
$normalisedExamples = $normalisedMap[$endpoint] ?? [];
755834

@@ -775,11 +854,7 @@ public function testCutExampleCloseToCharLimit(): void
775854
continue;
776855
}
777856

778-
$this->assertNotEmpty($normalisedExample, "The example response should not be empty for endpoint '$endpoint' and type '$type'.");
779-
$result = $this->annotationGenerator->cutExampleCloseToCharLimit($normalisedExample, $type);
780-
// Add a little wiggle room
781-
$this->assertLessThanOrEqual(AnnotationGenerator::EXAMPLE_CHAR_LIMIT + 30, strlen($result), "The example response should not exceed the character limit for endpoint '$endpoint' and type '$type'.");
782-
$this->assertEquals($expectedExample, $result, "The truncated example was not as expected for endpoint '$endpoint' and type '$type'.");
857+
yield "truncated example should match expected JSON for $endpoint endpoint and $type type" => [$endpoint, $type, $normalisedExample, $expectedExample];
783858
}
784859
}
785860
}
@@ -796,20 +871,34 @@ public function testBuildPropertyAnnotationFromJsonExample(): void
796871
$this->expectNotToPerformAssertions();
797872
}
798873

799-
public function testBuildSchemaAnnotationFromXmlExample(): void
874+
/**
875+
* @dataProvider getTestXmlSchemaData
876+
*
877+
* @param string $endpoint
878+
* @param array $normalisedObject
879+
* @param array $expected
880+
*
881+
* @return void
882+
*/
883+
public function testBuildSchemaAnnotationFromXmlExample(string $endpoint, array $normalisedObject, array $expected): void
884+
{
885+
$this->assertNotEmpty($normalisedObject, 'The decoded example response should not be empty for endpoint: ' . $endpoint);
886+
$result = $this->annotationGenerator->buildSchemaAnnotationFromXmlExample($normalisedObject);
887+
$this->assertEquals($expected, $result, "The XML schema was not as expected for endpoint $endpoint.");
888+
}
889+
890+
/**
891+
* @return iterable<string, array, array>
892+
*/
893+
public static function getTestXmlSchemaData(): iterable
800894
{
801-
$normalisedMap = $this->getExampleResponsesMap();
802-
$schemasMap = $this->getExampleResponsesMap(true);
895+
$normalisedMap = self::getNormalisedExamples();
896+
$schemasMap = self::getExampleSchemas();
803897
foreach (self::EXAMPLE_API_ENDPOINTS as $endpoint) {
804898
$normalisedString = $normalisedMap[$endpoint]['xml'] ?? '';
805-
$this->assertNotEmpty($normalisedString, 'The normalised example response should not be empty for endpoint: ' . $endpoint);
806899
$normalisedObject = json_decode($normalisedString, true) ?? [];
807-
$this->assertNotEmpty($normalisedObject, 'The decoded example response should not be empty for endpoint: ' . $endpoint);
808900
$expected = json_decode($schemasMap[$endpoint]['xml'] ?? '', true) ?? [];
809-
$result = $this->annotationGenerator->buildSchemaAnnotationFromXmlExample($normalisedObject);
810-
$result = json_encode($result);
811-
$expected = json_encode($expected);
812-
$this->assertEquals($expected, $result, "The XML schema was not as expected for endpoint $endpoint.");
901+
yield "should match expected XML schema for $endpoint endpoint" => [$endpoint, $normalisedObject, $expected];
813902
}
814903
}
815904

@@ -834,7 +923,7 @@ public function testRemoveTrailingCommaFromLastLine(array $lines, array $expecte
834923
}
835924

836925
/**
837-
* @return iterable<array, array}>
926+
* @return iterable<array, array>
838927
*/
839928
public function getTestDataForRemoveTrailingCommaFromLastLine(): iterable
840929
{
@@ -871,7 +960,7 @@ public function getTestDataForRemoveTrailingCommaFromLastLine(): iterable
871960
' )',
872961
' )',
873962
')',
874-
]
963+
],
875964
];
876965
}
877966

0 commit comments

Comments
 (0)