Skip to content

Commit dd2698c

Browse files
committed
#85995 generate controller without namespace
1 parent 0946988 commit dd2698c

File tree

7 files changed

+81
-14
lines changed

7 files changed

+81
-14
lines changed

src/Generators/BaseGenerator.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Ensi\LaravelOpenApiServerGenerator\Utils\TypesMapper;
99
use Illuminate\Filesystem\Filesystem;
1010
use InvalidArgumentException;
11+
use RuntimeException;
1112

1213
class BaseGenerator
1314
{
@@ -39,7 +40,20 @@ protected function trimPath(string $path): string
3940
return $path === '/' ? $path : ltrim($path, '/');
4041
}
4142

42-
protected function getNamespacedFilePath(string $fileName, string $namespace, ): string
43+
protected function getReplacedNamespace(?string $baseNamespace, string $replaceFromNamespace, string $replaceToNamespace): ?string
44+
{
45+
if ($baseNamespace) {
46+
if (!str_contains($baseNamespace, $replaceFromNamespace)) {
47+
throw new RuntimeException("Can't replace namespace");
48+
}
49+
50+
return str_replace($replaceFromNamespace, $replaceToNamespace, $baseNamespace);
51+
}
52+
53+
return null;
54+
}
55+
56+
protected function getNamespacedFilePath(string $fileName, ?string $namespace): string
4357
{
4458
$toDir = $this->psr4PathConverter->namespaceToPath($namespace);
4559

src/Generators/ControllersGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ private function extractControllers(SpecObjectInterface $specObject): array
3333

3434
$handler = $this->routeHandlerParser->parse($route->{'x-lg-handler'});
3535
$fqcn = $handler->fqcn;
36-
if (!$fqcn || !$handler->namespace) {
36+
if (!$fqcn) {
3737
continue;
3838
}
3939

src/Generators/RequestsGenerator.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use cebe\openapi\SpecObjectInterface;
66
use InvalidArgumentException;
7+
use RuntimeException;
78

89
class RequestsGenerator extends BaseGenerator implements GeneratorInterface
910
{
@@ -40,11 +41,13 @@ protected function extractRequests(SpecObjectInterface $specObject, array $names
4041
}
4142

4243
$handler = $this->routeHandlerParser->parse($route->{'x-lg-handler'});
43-
if (!$handler->namespace || !str_contains($handler->namespace, $replaceFromNamespace)) {
44+
45+
try {
46+
$newNamespace = $this->getReplacedNamespace($handler->namespace, $replaceFromNamespace, $replaceToNamespace);
47+
} catch (RuntimeException) {
4448
continue;
4549
}
4650

47-
$newNamespace = str_replace($replaceFromNamespace, $replaceToNamespace, $handler->namespace);
4851
$className = $route->{'x-lg-request-class-name'} ?? ucfirst($route->operationId) . 'Request';
4952
if (!$className) {
5053
continue;

src/Generators/TestsGenerator.php

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

55
use cebe\openapi\SpecObjectInterface;
66
use InvalidArgumentException;
7+
use RuntimeException;
78
use stdClass;
89

910
abstract class TestsGenerator extends BaseGenerator implements GeneratorInterface
@@ -47,11 +48,14 @@ protected function constructTests(stdClass $openApiData, array $namespaceData):
4748
}
4849

4950
$handler = $this->routeHandlerParser->parse($route->{'x-lg-handler'});
50-
if (!$handler->namespace || !str_contains($handler->namespace, $replaceFromNamespace)) {
51+
52+
try {
53+
$newNamespace = $this->getReplacedNamespace($handler->namespace, $replaceFromNamespace, $replaceToNamespace);
54+
} catch (RuntimeException) {
5155
continue;
5256
}
5357

54-
$newNamespace = str_replace($replaceFromNamespace, $replaceToNamespace, $handler->namespace);
58+
5559
$className = str_replace("Controller", "", $handler->class) . "ComponentTest";
5660
if (!$className) {
5761
continue;

src/Utils/PSR4PathConverter.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ public function addMappings(array $mappings): static
1919
return $this;
2020
}
2121

22-
public function namespaceToPath(string $namespace): string
22+
public function namespaceToPath(?string $namespace): string
2323
{
24+
if (is_null($namespace)) {
25+
return '';
26+
}
2427
foreach ($this->mappings as $mappingNamescape => $mappingPath) {
2528
if (str_starts_with($namespace, $mappingNamescape)) {
2629
$namespaceWithoutBase = substr($namespace, strlen($mappingNamescape));

tests/GenerateServerTest.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55
use Illuminate\Filesystem\Filesystem;
66
use Illuminate\Support\Facades\Config;
77
use function Pest\Laravel\artisan;
8+
use function PHPUnit\Framework\assertEquals;
89

10+
function makeFilePath(string $path): string
11+
{
12+
return str_replace('/', DIRECTORY_SEPARATOR, $path);
13+
}
914
test("Command GenerateServer success", function () {
1015
/** @var TestCase $this */
1116
$mapping = Config::get('openapi-server-generator.api_docs_mappings');
1217
$mappingValue = current($mapping);
13-
$mapping = [__DIR__ . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'index.yaml' => $mappingValue];
18+
$mapping = [makeFilePath(__DIR__ . '/resources/index.yaml') => $mappingValue];
1419
Config::set('openapi-server-generator.api_docs_mappings', $mapping);
1520

1621
$filesystem = $this->mock(Filesystem::class);
@@ -20,7 +25,35 @@
2025
})->andReturnUsing(function ($path) {
2126
return file_get_contents($path);
2227
});
23-
$filesystem->shouldReceive('put', 'cleanDirectory', 'ensureDirectoryExists');
28+
$filesystem->shouldReceive('cleanDirectory', 'ensureDirectoryExists');
29+
$appRoot = realpath(makeFilePath(__DIR__ . '/../vendor/orchestra/testbench-core/laravel/'));
30+
$putFiles = [];
31+
$filesystem->shouldReceive('put')->withArgs(function ($path, $content) use (&$putFiles, $appRoot) {
32+
$putFiles[] = str_replace($appRoot, '', $path);
33+
34+
return true;
35+
});
2436

2537
artisan(GenerateServer::class);
38+
39+
$needFiles = [
40+
makeFilePath('/app/Http/ApiV1/OpenApiGenerated/routes.php'),
41+
42+
makeFilePath('/app/Http/Controllers/ResourcesController.php'),
43+
makeFilePath('/app/Http/Requests/TestFullGenerateRequest.php'),
44+
makeFilePath('/app/Http/Tests/ResourcesComponentTest.php'),
45+
makeFilePath('/app/Http/Requests/TestFooRenameRequest.php'),
46+
47+
makeFilePath('/app/Http/Controllers/WithoutResponsesController.php'),
48+
49+
makeFilePath('/WithoutNamespaceController.php'),
50+
makeFilePath('/WithoutNamespaceRequest.php'),
51+
makeFilePath('/WithoutNamespaceComponentTest.php'),
52+
53+
makeFilePath('/app/Http/ApiV1/OpenApiGenerated/Enums/TestIntegerEnum.php'),
54+
makeFilePath('/app/Http/ApiV1/OpenApiGenerated/Enums/TestStringEnum.php'),
55+
];
56+
sort($needFiles);
57+
sort($putFiles);
58+
assertEquals($needFiles, $putFiles);
2659
});

tests/resources/index.yaml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ paths:
3030
responses:
3131
"200":
3232
description: Успешный ответ
33-
/resources:test-without-context:
33+
/resources:test-rename-request:
3434
post:
35-
operationId: testWithoutContext
36-
x-lg-handler: '\App\Http\Controllers\ResourcesController@testWithoutContext'
35+
operationId: testRenameRequest
36+
x-lg-handler: '\App\Http\Controllers\ResourcesController@testRenameRequest'
37+
x-lg-request-class-name: 'TestFooRenameRequest'
3738
responses:
3839
"200":
3940
description: Успешный ответ
@@ -46,6 +47,7 @@ paths:
4647
/resources:test-with-skip:
4748
post:
4849
operationId: testWithSkip
50+
x-lg-handler: '\App\Http\Controllers\SkipController@testWithSkip'
4951
x-lg-skip-controller-generation: true
5052
x-lg-skip-request-generation: true
5153
x-lg-skip-tests-generation: true
@@ -55,14 +57,22 @@ paths:
5557
/resources:test-bad-handler:
5658
post:
5759
operationId: testBadHandler
58-
x-lg-handler: 'bad'
60+
x-lg-handler: ''
61+
responses:
62+
"200":
63+
description: Успешный ответ
64+
/resources:test-global-namespace:
65+
post:
66+
operationId: withoutNamespace
67+
x-lg-handler: 'WithoutNamespaceController@testWithoutContext'
5968
responses:
6069
"200":
6170
description: Успешный ответ
6271
/resources:test-without-responses:
6372
post:
6473
operationId: testWithoutResponses
65-
x-lg-handler: '\App\Http\Controllers\ResourcesController@testWithoutResponses'
74+
x-lg-handler: '\App\Http\Controllers\WithoutResponsesController@testWithoutResponses'
75+
x-lg-skip-request-generation: true
6676

6777
components:
6878
responses:

0 commit comments

Comments
 (0)