{"id":37233479,"url":"https://github.com/n4m-ward/perry","last_synced_at":"2026-01-15T03:54:19.721Z","repository":{"id":295470923,"uuid":"880522118","full_name":"n4m-ward/perry","owner":"n4m-ward","description":"A swagger generator library using e2e tests for laravel","archived":false,"fork":false,"pushed_at":"2025-06-15T19:00:03.000Z","size":186,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-30T03:41:04.908Z","etag":null,"topics":["api","documentation","laravel","swagger","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/n4m-ward.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-29T21:54:19.000Z","updated_at":"2025-06-15T18:54:27.000Z","dependencies_parsed_at":"2025-06-04T20:51:29.557Z","dependency_job_id":null,"html_url":"https://github.com/n4m-ward/perry","commit_stats":null,"previous_names":["n4m-ward/perry"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/n4m-ward/perry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n4m-ward%2Fperry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n4m-ward%2Fperry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n4m-ward%2Fperry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n4m-ward%2Fperry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/n4m-ward","download_url":"https://codeload.github.com/n4m-ward/perry/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n4m-ward%2Fperry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28419272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","documentation","laravel","swagger","unit-testing"],"created_at":"2026-01-15T03:54:19.171Z","updated_at":"2026-01-15T03:54:19.708Z","avatar_url":"https://github.com/n4m-ward.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Perry - Swagger generator library using e2e tests\n\n---\n\n## Summary\n\n### [Setup](#setup)\n### [Creating Tests](#creating-tests)\n### [Usage examples](#usage-examples)\n### [Doing assertions](#doing-assertions)\n\n---\n\n# Setup\n\n#### Install the library:\n\n```shell\ncomposer require n4m-ward/laravel-perry --dev\n```\n\n#### Run the following command once to generate the configuration files\n\n```shell\n./vendor/bin/perry\n```\n\nAfter running the command above, two files will be created\n\n- A `perry.json` file containing the following data:\n\n```json\n{\n    \"testsFolderPath\": \"/tests/Perry\",\n    \"testExecutorPath\": \"/vendor/bin/phpunit\",\n    \"swaggerOutputPath\": \"/perry_output/swagger\",\n    \"cacheOutputPath\": \"/perry_output/cache\"\n}\n```\n\n- A `BaseTestCase.php` file that you will extend in your e2e tests\n- The `BaseTestCase` will be created in the following path: `/tests/Perry/BaseTestCase.php`\n- You can change the path of this file if you want, or use your own `BaseTestCase`\n\n```php\n\u003c?php\n\nnamespace Tests\\Perry;\n\nuse Perry\\Attributes\\Info;\nuse Perry\\Attributes\\Server;\nuse Perry\\Attributes\\Servers;\nuse Perry\\PerryHttp\\PerryHttpRequest;\nuse Illuminate\\Foundation\\Testing\\TestCase as LaravelTestCase;\n\n#[Servers(\n    new Server(description: 'Example server local', url: 'http://localhost:8000')\n)]\n#[Info(\n    version: '1.0.0',\n    title: 'Example server title',\n    description: 'Example server description',\n    contactEmail: 'test@example.com',\n    termsOfService: 'https://example.com/terms-of-service', // optional parameter\n    externalDocs: new ExternalDocs( // optional parameter\n        url: 'https://example.com/external-docs',\n        description: 'Find more info here',\n    ),\n)]\nabstract class BaseTestCase extends LaravelTestCase\n{\n    use PerryHttpRequest;\n}\n\n```\n\n---\n\n# Creating Tests\n\n- First, create a class extending the `BaseTestCase` created above\n- For example, an `UserControllerTest`\n\n- Then let's create our first e2e test\n\n```php\npublic function test_shouldCreateUser() {\n    $this\n        -\u003eperryHttp()\n        -\u003ewithBody([\n            'name' =\u003e 'John Doe',\n            'age' =\u003e 25,\n            'email' =\u003e 'john@doe.com',\n            'password' =\u003e 'password',\n        ])\n        -\u003epost('/user')\n        -\u003eassertJson(['success' =\u003e true])\n        -\u003eassertStatus(Response::HTTP_CREATED);\n\n    $this-\u003eassertDatabaseHas('users', [\n        'name' =\u003e 'John Doe',\n        'age' =\u003e 25,\n        'email' =\u003e 'john@doe.com',\n    ]);\n}\n```\n\n- Then run the following command\n\n```shell\n./vendor/bin/perry\n```\n\n- So, the following documentation will be created on the path `perry_output/swagger/output.yaml`\n\n```yaml\nopenapi: 3.0.0\nservers:\n    - { description: 'Server Local', url: 'http://localhost:8080' }\ninfo:\n  version: 1.0.0\n  title: 'Example server title'\n  description: 'Example server description'\n  contact: { email: test@example.com }\n  termsOfService: 'https://example.com/terms-of-service'\nexternalDocs:\n  description: 'Find more info here'\n  url: 'https://example.com/external-docs'\npaths:\n    /user: { post: { summary: 'should create user', description: 'should create user', operationId: test_shouldCreateUser, responses: { 201: { description: '201', content: { application/json: { schema: { type: object, properties: { success: { type: boolean, example: true } } } } } } }, requestBody: { description: 'should create user', content: { application/json: { schema: { type: object, properties: { name: { type: string, example: 'John Doe' }, age: { type: integer, format: int32, example: 25 }, email: { type: string, example: john@doe.com }, password: { type: string, example: password } } } } } } } }\n\n```\n\n![Swagger example for create user endpoint](documentation/images/example_swagger_should_create_user.png)\n\n---\n\n# Usage examples\n\n### Request using header\n\n```php\npublic function test_exampleWithHeaders(): void\n{\n    $this\n        -\u003eperryHttp()\n        -\u003ewithHeaders([\n            'Authorization' =\u003e 'Bearer token',\n        ])\n        -\u003eget('/api/example');\n}\n```\n\n### Request using body\n\n```php\npublic function test_exampleWithHeaders(): void\n{\n    $this\n        -\u003eperryHttp()\n        -\u003ewithBody([\n            'foo' =\u003e 'bar',\n        ])\n        -\u003epost('/api/example');\n}\n```\n\n\n### Request using body and headers\n\n```php\npublic function test_exampleWithHeadersAndBody(): void\n{\n    $this\n        -\u003eperryHttp()\n        -\u003ewithHeaders([\n            'Authorization' =\u003e 'Bearer token',\n        ])\n        -\u003ewithBody([\n            'foo' =\u003e 'bar',\n        ])\n        -\u003epost('/api/example');\n}\n```\n\n### Available http methods\n\n```php\npublic function test_get(): void\n{\n    $this-\u003eperryHttp()-\u003eget('/api/example/123');\n}\n\npublic function test_post(): void\n{\n    $this\n        -\u003eperryHttp()\n        -\u003ewithBody(['foo' =\u003e 'bar'])\n        -\u003epost('/api/example');\n}\n\npublic function test_put(): void\n{\n    $this\n        -\u003eperryHttp()\n        -\u003ewithBody(['foo' =\u003e 'bar'])\n        -\u003eput('/api/example/123');\n}\n\npublic function test_patch(): void\n{\n    $this\n        -\u003eperryHttp()\n        -\u003ewithBody(['foo' =\u003e 'bar'])\n        -\u003epatch('/api/example/123');\n}\n\npublic function test_delete(): void\n{\n    $this-\u003eperryHttp()-\u003edelete('/api/example/123');\n}\n```\n\n### Using securityScheme\n\nFirst, on your TestCase or your BaseTestCase, add the following attribute\n\n```php\n#[SecurityScheme(securityScheme: 'BearerToken', type: 'http', scheme: 'bearer')]\nclass SomeTest extends BaseTestCase {}\n```\n\nThen, on your test method, add the following attribute\n\n```php\n#[UseSecurityScheme('BearerToken')]\npublic function test_shouldCreateUser(): void\n{\n}\n```\n\n### Using tags\n\nFirst add the `Tag` attribute on your TestCase or your BaseTestCase\n\n```php\n#[\\Perry\\Attributes\\Tag\\Tag(name: 'User', description: \"User related endpoints\")]\nclass SomeTest extends BaseTestCase {}\n```\n\nIf you want, you can add the externalDocs to your tag\n\n```php\n#[\\Perry\\Attributes\\Tag\\Tag(\n    name: 'User', \n    description: \"User related endpoints\"\n    externalDocs: new \\Perry\\Attributes\\ExternalDocs(\n        url: 'https://example.com/external-docs',\n        description: 'Find more info here',\n)]\nclass SomeTest extends BaseTestCase {}\n```\n\nThen, on your test method, add the `UsingTag` attribute\n\n```php\n#[\\Perry\\Attributes\\Tag\\UsingTag('User')]\npublic function test_shouldCreateUser(): void\n{\n}\n```\n\n# Doing assertions\n\n- **The method `perryHttp()` will return an `Illuminate\\Testing\\TestResponse`**\n- With the `TestResponse`, we can do some assertions as we can see bellow\n- You can see all available assertions for `TestResponse` [Clicking here](https://laravel.com/docs/11.x/http-tests)\n\n```php\npublic function test_shouldMakeHttpRequest_AndValidateResponseBody(): void\n{\n    $this\n        -\u003eperryHttp()\n        -\u003eget('/user/123')\n        -\u003eassertJson([\n            'name' =\u003e 'John Doe',\n            'age' =\u003e 25,\n            'email' =\u003e 'john@doe.com',\n            'password' =\u003e 'password',\n        ])\n        -\u003eassertStatus(Response::HTTP_OK);\n}\n\npublic function test_shouldDoHttpRequest_AndValidateIsUnauthorized(): void\n{\n    $this\n        -\u003eperryHttp()\n        -\u003edelete('/user/123')\n        -\u003eassertJson([\n            'message' =\u003e 'Unauthorized',\n        ])\n        -\u003eassertUnauthorized();\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fn4m-ward%2Fperry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fn4m-ward%2Fperry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fn4m-ward%2Fperry/lists"}