Skip to content

Commit 03b0068

Browse files
authored
Merge pull request #6 from ensi-platform/task-85627
Task 85627
2 parents 98be5e3 + bf4ddc7 commit 03b0068

File tree

8 files changed

+168
-32
lines changed

8 files changed

+168
-32
lines changed

.github/workflows/run-tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ jobs:
1313
fail-fast: true
1414
matrix:
1515
os: [ubuntu-latest, windows-latest]
16-
php: [8.0]
16+
php: [8.1]
1717
laravel: [8.*]
1818
stability: [prefer-lowest, prefer-stable]
1919
include:
2020
- laravel: 8.*
21-
testbench: ^6.6
21+
testbench: ^6.23
2222

2323
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}
2424

composer.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
],
1111
"license": "MIT",
1212
"require": {
13-
"php": "^8.0",
13+
"php": "^8.1",
1414
"cebe/php-openapi": ">=1.4.2 <1.6.0"
1515
},
1616
"autoload": {
@@ -47,6 +47,10 @@
4747
"test-coverage": "XDEBUG_MODE=coverage ./vendor/bin/pest --coverage"
4848
},
4949
"config": {
50-
"sort-packages": true
50+
"sort-packages": true,
51+
"allow-plugins": {
52+
"composer/package-versions-deprecated": true,
53+
"pestphp/pest-plugin": true
54+
}
5155
}
5256
}

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Generators/BaseGenerator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Ensi\LaravelOpenApiServerGenerator\Generators;
44

5+
use Ensi\LaravelOpenApiServerGenerator\Utils\PhpDocGenerator;
56
use Ensi\LaravelOpenApiServerGenerator\Utils\PSR4PathConverter;
67
use Ensi\LaravelOpenApiServerGenerator\Utils\RouteHandlerParser;
78
use Ensi\LaravelOpenApiServerGenerator\Utils\TemplatesManager;
@@ -20,6 +21,7 @@ public function __construct(
2021
protected PSR4PathConverter $psr4PathConverter,
2122
protected RouteHandlerParser $routeHandlerParser,
2223
protected TypesMapper $typesMapper,
24+
protected PhpDocGenerator $phpDocGenerator,
2325
) {
2426
}
2527

src/Generators/EnumsGenerator.php

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ public function generate(SpecObjectInterface $specObject): void
2525
$enums = $this->extractEnums($openApiData);
2626

2727
$template = $this->templatesManager->getTemplate('Enum.template');
28-
foreach ($enums as $className => $schema) {
29-
$enumType = get_debug_type($schema->enum[0]);
28+
foreach ($enums as $enumName => $schema) {
29+
$enumType = $this->getEnumType($schema, $enumName);
3030
$this->filesystem->put(
31-
rtrim($toDir, '/') . "/{$className}.php",
31+
rtrim($toDir, '/') . "/{$enumName}.php",
3232
$this->replacePlaceholders($template, [
3333
'{{ namespace }}' => $namespace,
34-
'{{ className }}' => $className,
35-
'{{ constants }}' => $this->convertEnumSchemaToConstants($schema),
34+
'{{ enumName }}' => $enumName,
35+
'{{ cases }}' => $this->convertEnumSchemaToCases($schema),
3636
'{{ enumType }}' => $enumType,
37-
'{{ valuesArray }}' => $this->convertEnumSchemaToValuesArray($schema),
37+
'{{ enumPhpDoc }}' => $this->convertEnumSchemaToPhpDoc($schema),
3838
])
3939
);
4040
}
@@ -47,29 +47,38 @@ private function extractEnums(stdClass $openApiData): array
4747
return array_filter($schemas, fn ($schema) => !empty($schema->enum));
4848
}
4949

50-
private function convertEnumSchemaToConstants(stdClass $schema): string
50+
private function getEnumType(stdClass $schema, string $enumName): string
51+
{
52+
return match ($schema->type) {
53+
"integer" => "int",
54+
"string" => "string",
55+
default => throw new LogicException("Enum {$enumName} has invalid type '{$schema->type}'. Supported types are: ['integer', 'string']"),
56+
};
57+
}
58+
59+
private function convertEnumSchemaToCases(stdClass $schema): string
5160
{
5261
$result = '';
5362
foreach ($schema->enum as $i => $enum) {
5463
$varName = $schema->{'x-enum-varnames'}[$i] ?? null;
5564
if ($varName === null) {
5665
throw new LogicException("x-enum-varnames for enum \"{$enum}\" is not set");
5766
}
67+
$description = $schema->{'x-enum-descriptions'}[$i] ?? null;
68+
if ($description) {
69+
$result .= " /** {$description} */\n";
70+
}
5871
$value = var_export($enum, true);
59-
$result .= " public const {$varName} = {$value};\n";
72+
$result .= " case {$varName} = {$value};\n";
6073
}
6174

62-
return $result;
75+
return rtrim($result, "\n");
6376
}
6477

65-
private function convertEnumSchemaToValuesArray(stdClass $schema): string
78+
private function convertEnumSchemaToPhpDoc(stdClass $schema): string
6679
{
67-
$result = "[\n";
68-
foreach ($schema->{'x-enum-varnames'} as $varName) {
69-
$result .= " self::{$varName},\n";
70-
}
71-
$result .= ' ]';
72-
73-
return $result;
80+
return $schema->description
81+
? "\n" . $this->phpDocGenerator->fromText(text: $schema->description, deleteEmptyLines: true)
82+
: "\n";
7483
}
7584
}

src/Utils/PhpDocGenerator.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Ensi\LaravelOpenApiServerGenerator\Utils;
4+
5+
class PhpDocGenerator
6+
{
7+
public function fromText(string $text, int $spaces = 0, bool $deleteEmptyLines = false): string
8+
{
9+
$eol = PHP_EOL;
10+
$result = $this->prependSpaces("/**{$eol}", $spaces);
11+
foreach ($this->convertTextToLines($text, $deleteEmptyLines) as $line) {
12+
$result .= $this->prependSpaces(" * {$this->safeLine($line)}{$eol}", $spaces);
13+
}
14+
$result .= $this->prependSpaces(" */", $spaces);
15+
16+
return $result;
17+
}
18+
19+
private function prependSpaces(string $result, int $spaces = 0): string
20+
{
21+
return str_repeat(' ', $spaces) . $result;
22+
}
23+
24+
private function safeLine(string $line): string
25+
{
26+
return str_replace('*/', '', $line);
27+
}
28+
29+
private function convertTextToLines(string $text, bool $deleteEmptyLines): array
30+
{
31+
$lines = explode("\n", $text);
32+
$trimmedLines = array_map(fn ($line) => trim($line), $lines);
33+
34+
return $deleteEmptyLines ? array_filter($trimmedLines) : $trimmedLines;
35+
}
36+
}

templates/Enum.template

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,8 @@
66
*/
77

88
namespace {{ namespace }};
9-
10-
class {{ className }}
9+
{{ enumPhpDoc }}
10+
enum {{ enumName }}: {{ enumType }}
1111
{
12-
{{ constants }}
13-
/**
14-
* @return {{ enumType }}[]
15-
*/
16-
public static function cases(): array
17-
{
18-
return {{ valuesArray }};
19-
}
12+
{{ cases }}
2013
}

tests/PhpDocGeneratorTest.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
use Ensi\LaravelOpenApiServerGenerator\Utils\PhpDocGenerator;
4+
5+
it('can generate phpdoc from single line string', function () {
6+
$generator = new PhpDocGenerator();
7+
$result = $generator->fromText("some text");
8+
9+
$expected = <<<"EOD"
10+
/**
11+
* some text
12+
*/
13+
EOD;
14+
expect($result)->toEqual($expected);
15+
});
16+
17+
it('can generate phpdoc from with prepending spaces', function () {
18+
$generator = new PhpDocGenerator();
19+
$result = $generator->fromText("some text", 4);
20+
21+
$expected = <<<"EOD"
22+
/**
23+
* some text
24+
*/
25+
EOD;
26+
expect($result)->toEqual($expected);
27+
});
28+
29+
it('can generate phpdoc from multiline string', function () {
30+
$generator = new PhpDocGenerator();
31+
$multilineString = <<<'EOT'
32+
This is a test comment
33+
It is also multiline
34+
Wow
35+
EOT;
36+
$result = $generator->fromText($multilineString, 4);
37+
38+
$expected = <<<"EOD"
39+
/**
40+
* This is a test comment
41+
* It is also multiline
42+
* Wow
43+
*/
44+
EOD;
45+
expect($result)->toEqual($expected);
46+
});
47+
48+
it('erases phpdoc end', function () {
49+
$generator = new PhpDocGenerator();
50+
$result = $generator->fromText("broken */text");
51+
52+
$expected = <<<"EOD"
53+
/**
54+
* broken text
55+
*/
56+
EOD;
57+
expect($result)->toEqual($expected);
58+
});
59+
60+
it('trims lines', function () {
61+
$generator = new PhpDocGenerator();
62+
$result = $generator->fromText(" some text ");
63+
64+
$expected = <<<"EOD"
65+
/**
66+
* some text
67+
*/
68+
EOD;
69+
expect($result)->toEqual($expected);
70+
});
71+
72+
it('deletes empty lines if configured', function () {
73+
$generator = new PhpDocGenerator();
74+
$multilineString = <<<'EOT'
75+
This is a test comment
76+
77+
It is also multiline
78+
And with empty line
79+
Wow
80+
EOT;
81+
$result = $generator->fromText($multilineString, deleteEmptyLines: true);
82+
83+
$expected = <<<"EOD"
84+
/**
85+
* This is a test comment
86+
* It is also multiline
87+
* And with empty line
88+
* Wow
89+
*/
90+
EOD;
91+
expect($result)->toEqual($expected);
92+
});

0 commit comments

Comments
 (0)