From eb3151aa3bea3cc745718df62f19d42c1beb0bec Mon Sep 17 00:00:00 2001 From: Kit Loong Date: Thu, 10 Nov 2022 18:11:21 +0800 Subject: [PATCH] Increase UT coverage --- .gitattributes | 1 + .gitignore | 1 + composer.json | 5 ++- phpcs.xml | 3 ++ src/LaravelRequestDocs.php | 21 ++++------ src/LaravelRequestDocsFacade.php | 1 + src/LaravelRequestDocsServiceProvider.php | 5 +++ tests/ExampleTest.php | 12 ------ .../LaravelRequestDocsCommandTest.php | 42 +++++++++++++++++++ .../LaravelRequestDocsControllerTest.php | 29 +++++++++++++ tests/LRDOpenApiTest.php | 6 +-- tests/LRDTest.php | 33 +++++++++------ tests/TestCase.php | 11 ++++- .../SingleActionController.php | 16 +++++++ tests/TestControllers/TelescopeController.php | 16 +++++++ tests/TestControllers/WelcomeController.php | 12 ++++++ tests/TestRequests/WelcomeIndexRequest.php | 5 +++ tests/TestRequests/WelcomeStoreRequest.php | 1 + tests/TestRules/Uppercase.php | 23 ++++++++++ 19 files changed, 198 insertions(+), 45 deletions(-) delete mode 100644 tests/ExampleTest.php create mode 100644 tests/Feature/Commands/LaravelRequestDocsCommandTest.php create mode 100644 tests/Feature/Controllers/LaravelRequestDocsControllerTest.php create mode 100644 tests/TestControllers/SingleActionController.php create mode 100644 tests/TestControllers/TelescopeController.php create mode 100644 tests/TestRules/Uppercase.php diff --git a/.gitattributes b/.gitattributes index 886475c..7289a91 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9,6 +9,7 @@ /tests export-ignore /.editorconfig export-ignore /.php_cs.dist export-ignore +/_ide_helper.php export-ignore /psalm.xml export-ignore /psalm.xml.dist export-ignore /testbench.yaml export-ignore diff --git a/.gitignore b/.gitignore index 33cc57c..99e05e4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ vendor node_modules .php-cs-fixer.cache .DS_Store +_ide_helper.php diff --git a/composer.json b/composer.json index d1a752c..dca826c 100644 --- a/composer.json +++ b/composer.json @@ -19,9 +19,11 @@ "php": "^7.4|^8.0", "illuminate/contracts": "^8.37|^9.0", "kitloong/laravel-app-logger": "^1.0", - "spatie/laravel-package-tools": "^1.4.3" + "spatie/laravel-package-tools": "^1.4.3", + "ext-json": "*" }, "require-dev": { + "barryvdh/laravel-ide-helper": "^2.12", "brianium/paratest": "^6.2", "friendsofphp/php-cs-fixer": "^3.5", "nunomaduro/collision": "^5.3|^6.0", @@ -43,6 +45,7 @@ }, "scripts": { "psalm": "vendor/bin/psalm", + "phpcs": "vendor/bin/phpcs", "test": "./vendor/bin/testbench package:test --parallel --no-coverage", "test-coverage": "vendor/bin/phpunit --coverage-html coverage" }, diff --git a/phpcs.xml b/phpcs.xml index d314786..5508ac9 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,6 +1,9 @@ Standard Based on PSR2 + src + tests + tests/* diff --git a/src/LaravelRequestDocs.php b/src/LaravelRequestDocs.php index 0913dff..de66162 100644 --- a/src/LaravelRequestDocs.php +++ b/src/LaravelRequestDocs.php @@ -11,7 +11,7 @@ class LaravelRequestDocs { - public function getDocs() + public function getDocs(): array { $docs = []; $excludePatterns = config('request-docs.hide_matching') ?? []; @@ -68,6 +68,7 @@ public function getControllersInfo(): array $routes = collect(Route::getRoutes()); $onlyRouteStartWith = config('request-docs.only_route_uri_start_with') ?? ''; + /** @var \Illuminate\Routing\Route $route */ foreach ($routes as $route) { if ($onlyRouteStartWith && !Str::startsWith($route->uri, $onlyRouteStartWith)) { continue; @@ -75,13 +76,14 @@ public function getControllersInfo(): array try { $actionControllerName = $route->action['controller'] ?? $route->action["0"]; - /// Show Pnly Controller Name + /// Show Only Controller Name $controllerFullPath = explode('@', $actionControllerName)[0]; $getStartWord = strrpos(explode('@', $actionControllerName)[0], '\\') + 1; $controllerName = substr($controllerFullPath, $getStartWord); $method = explode('@', $actionControllerName)[1] ?? '__invoke'; $httpMethod = $route->methods[0]; + foreach ($controllersInfo as $controllerInfo) { if ($controllerInfo['uri'] == $route->uri && $controllerInfo['httpMethod'] == $httpMethod) { // is duplicate @@ -113,7 +115,7 @@ public function getControllersInfo(): array return $controllersInfo; } - public function appendRequestRules(array $controllersInfo) + public function appendRequestRules(array $controllersInfo): array { foreach ($controllersInfo as $index => $controllerInfo) { $controller = $controllerInfo['controller_full_path']; @@ -121,8 +123,9 @@ public function appendRequestRules(array $controllersInfo) try { $reflectionMethod = new ReflectionMethod($controller, $method); } catch (Throwable $e) { + // Skip to next if controller is not exists. if (config('request-docs.debug')) { - throw $e; + throw $e; // @codeCoverageIgnore } continue; } @@ -187,16 +190,6 @@ public function lrdDocComment($docComment): string return $lrdComment; } - // get text between first and last tag - private function getTextBetweenTags($docComment, $tag1, $tag2) - { - $docComment = trim($docComment); - $start = strpos($docComment, $tag1); - $end = strpos($docComment, $tag2); - $text = substr($docComment, $start + strlen($tag1), $end - $start - strlen($tag1)); - return $text; - } - public function flattenRules($mixedRules) { $rules = []; diff --git a/src/LaravelRequestDocsFacade.php b/src/LaravelRequestDocsFacade.php index c21ecef..4c453c2 100644 --- a/src/LaravelRequestDocsFacade.php +++ b/src/LaravelRequestDocsFacade.php @@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Facade; /** + * @codeCoverageIgnore * @see \Rakutentech\LaravelRequestDocs\LaravelRequestDocs */ class LaravelRequestDocsFacade extends Facade diff --git a/src/LaravelRequestDocsServiceProvider.php b/src/LaravelRequestDocsServiceProvider.php index f7d1f98..6154d17 100644 --- a/src/LaravelRequestDocsServiceProvider.php +++ b/src/LaravelRequestDocsServiceProvider.php @@ -22,6 +22,11 @@ public function configurePackage(Package $package): void ->hasViews() ->hasAssets() ->hasCommand(LaravelRequestDocsCommand::class); + } + + public function packageBooted() + { + parent::packageBooted(); Route::get(config('request-docs.url'), [\Rakutentech\LaravelRequestDocs\Controllers\LaravelRequestDocsController::class, 'index']) ->name('request-docs.index') diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php deleted file mode 100644 index 21224ca..0000000 --- a/tests/ExampleTest.php +++ /dev/null @@ -1,12 +0,0 @@ -assertTrue(true); - } -} diff --git a/tests/Feature/Commands/LaravelRequestDocsCommandTest.php b/tests/Feature/Commands/LaravelRequestDocsCommandTest.php new file mode 100644 index 0000000..bcec407 --- /dev/null +++ b/tests/Feature/Commands/LaravelRequestDocsCommandTest.php @@ -0,0 +1,42 @@ +assertFalse(File::exists(config('request-docs.docs_path') . '/index.html')); + $this->assertFalse(File::exists(config('request-docs.docs_path') . '/lrd-openapi.json')); + + $this->artisan('lrd:generate') + ->assertExitCode(0); + + $this->assertTrue(File::exists(config('request-docs.docs_path') . '/index.html')); + $this->assertTrue(File::exists(config('request-docs.docs_path') . '/lrd-openapi.json')); + + config('request-docs.docs_path'); + } + + public function testWillCreateDirectory() + { + File::deleteDirectory(config('request-docs.docs_path')); + $this->assertFalse(File::exists(config('request-docs.docs_path'))); + + $this->artisan('lrd:generate') + ->assertExitCode(0); + + $this->assertTrue(File::exists(config('request-docs.docs_path'))); + } +} diff --git a/tests/Feature/Controllers/LaravelRequestDocsControllerTest.php b/tests/Feature/Controllers/LaravelRequestDocsControllerTest.php new file mode 100644 index 0000000..245cf5b --- /dev/null +++ b/tests/Feature/Controllers/LaravelRequestDocsControllerTest.php @@ -0,0 +1,29 @@ +get(config('request-docs.url')) + ->assertStatus(Response::HTTP_OK); + } + + public function testSortDocsByDefault() + { + Config::set('request-docs.sort_by', 'default'); + $this->get(config('request-docs.url')) + ->assertStatus(Response::HTTP_OK); + } + + public function testOpenAPI() + { + $this->get(config('request-docs.url') . '?openapi=true') + ->assertStatus(Response::HTTP_OK); + } +} diff --git a/tests/LRDOpenApiTest.php b/tests/LRDOpenApiTest.php index e309b0c..64d4981 100644 --- a/tests/LRDOpenApiTest.php +++ b/tests/LRDOpenApiTest.php @@ -1,7 +1,6 @@ lrd->getDocs(); $openApi = $this->lrdToOpenApi->openApi($docs)->toArray(); - $routes = collect(Route::getRoutes()); - $this->assertSame($routes->count(), count($docs)); + $this->assertSame($this->countRoutesWithLRDDoc(), count($docs)); $countRoutes = 0; foreach ($openApi["paths"] as $path) { $countRoutes += count(array_keys($path)); } - $this->assertSame($routes->count(), $countRoutes); + $this->assertSame($this->countRoutesWithLRDDoc(), $countRoutes); } } diff --git a/tests/LRDTest.php b/tests/LRDTest.php index 63d0522..ba2a15e 100644 --- a/tests/LRDTest.php +++ b/tests/LRDTest.php @@ -1,16 +1,29 @@ lrd->getDocs(); - $routes = collect(Route::getRoutes()); - $this->assertSame($routes->count(), count($docs)); + $this->assertSame($this->countRoutesWithLRDDoc(), count($docs)); + + $docSize = 9; + $firstDoc = $docs[0]; + $this->assertCount($docSize, $firstDoc); + $this->assertArrayHasKey('uri', $firstDoc); + $this->assertArrayHasKey('methods', $firstDoc); + $this->assertArrayHasKey('middlewares', $firstDoc); + $this->assertArrayHasKey('controller', $firstDoc); + $this->assertArrayHasKey('controller_full_path', $firstDoc); + $this->assertArrayHasKey('method', $firstDoc); + $this->assertArrayHasKey('httpMethod', $firstDoc); + $this->assertArrayHasKey('rules', $firstDoc); + $this->assertArrayHasKey('docBlock', $firstDoc); } public function testDocsCanFetchAllMethods() @@ -25,18 +38,12 @@ public function testDocsCanFetchAllMethods() $this->assertSame(['DELETE', 'GET', 'HEAD', 'POST', 'PUT'], $methods); } - public function testDocsCanFetchInfo() + public function testOnlyRouteURIStartWith() { + Config::set('request-docs.only_route_uri_start_with', 'welcome'); $docs = $this->lrd->getDocs(); foreach ($docs as $doc) { - $this->assertNotEmpty($doc['rules']); - $this->assertNotEmpty($doc['methods']); - // $this->assertNotEmpty($doc['middlewares']); //todo: add middlewares to test - $this->assertNotEmpty($doc['controller']); - $this->assertNotEmpty($doc['controller_full_path']); - $this->assertNotEmpty($doc['method']); - $this->assertNotEmpty($doc['httpMethod']); - $this->assertNotEmpty($doc['rules']); + $this->assertStringStartsWith('welcome', $doc['uri']); } } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 653fd5f..018a7ea 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -35,8 +35,17 @@ public function getEnvironmentSetUp($app) public function registerRoutes() { Route::get('/', [TestControllers\WelcomeController::class, 'index']); Route::get('welcome', [TestControllers\WelcomeController::class, 'index']); - Route::post('welcome', [TestControllers\WelcomeController::class, 'store']); + Route::post('welcome', [TestControllers\WelcomeController::class, 'store'])->middleware('auth:api'); Route::put('welcome', [TestControllers\WelcomeController::class, 'edit']); Route::delete('welcome', [TestControllers\WelcomeController::class, 'destroy']); + Route::get('single', TestControllers\SingleActionController::class); + + // Expected to be skipped + Route::get('telescope', [TestControllers\TelescopeController::class, 'index']); + } + + protected function countRoutesWithLRDDoc(): int + { + return count(Route::getRoutes()) - 2; // Exclude `telescope`, `request-docs` } } diff --git a/tests/TestControllers/SingleActionController.php b/tests/TestControllers/SingleActionController.php new file mode 100644 index 0000000..73e40c3 --- /dev/null +++ b/tests/TestControllers/SingleActionController.php @@ -0,0 +1,16 @@ + ['nullable', 'string', 'min:5', 'max:255'], + 'title' => new Uppercase(), + 'file' => 'file', + 'image' => 'image', 'page' => 'nullable|integer|min:1', 'per_page' => 'nullable|integer|min:1|max:100', ]; diff --git a/tests/TestRequests/WelcomeStoreRequest.php b/tests/TestRequests/WelcomeStoreRequest.php index a2d27a4..a42002f 100644 --- a/tests/TestRequests/WelcomeStoreRequest.php +++ b/tests/TestRequests/WelcomeStoreRequest.php @@ -28,6 +28,7 @@ protected function prepareForValidation() public function rules() { return [ + 'error' => ['string', 'exists:' . $this->user->id], 'message_param' => 'nullable|string', ]; } diff --git a/tests/TestRules/Uppercase.php b/tests/TestRules/Uppercase.php new file mode 100644 index 0000000..0a4bfde --- /dev/null +++ b/tests/TestRules/Uppercase.php @@ -0,0 +1,23 @@ +