{"id":15525374,"url":"https://github.com/ghostwriter/psalm-sandbox","last_synced_at":"2025-04-23T08:54:00.519Z","repository":{"id":177925342,"uuid":"661099833","full_name":"ghostwriter/psalm-sandbox","owner":"ghostwriter","description":"Provides a framework for testing Psalm plugins with PHPUnit","archived":false,"fork":false,"pushed_at":"2025-02-11T00:33:21.000Z","size":515,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"0.2.x","last_synced_at":"2025-02-19T19:04:35.112Z","etag":null,"topics":["ghostwriter","psalm-plugin","psalm-plugin-tester"],"latest_commit_sha":null,"homepage":"https://github.com/ghostwriter/psalm-plugin","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ghostwriter.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["ghostwriter"]}},"created_at":"2023-07-01T19:37:06.000Z","updated_at":"2025-02-11T00:33:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"e11bc095-77a4-42df-bce0-18f4e8974a5d","html_url":"https://github.com/ghostwriter/psalm-sandbox","commit_stats":null,"previous_names":["ghostwriter/psalm-plugin-tester","ghostwriter/psalm-sandbox"],"tags_count":6,"template":false,"template_full_name":"ghostwriter/wip","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fpsalm-sandbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fpsalm-sandbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fpsalm-sandbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghostwriter%2Fpsalm-sandbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ghostwriter","download_url":"https://codeload.github.com/ghostwriter/psalm-sandbox/tar.gz/refs/heads/0.2.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242018607,"owners_count":20058648,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["ghostwriter","psalm-plugin","psalm-plugin-tester"],"created_at":"2024-10-02T10:57:08.384Z","updated_at":"2025-04-23T08:54:00.499Z","avatar_url":"https://github.com/ghostwriter.png","language":"PHP","funding_links":["https://github.com/sponsors/ghostwriter"],"categories":[],"sub_categories":[],"readme":"# Psalm Sandbox\n\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/ghostwriter?label=Sponsor+@ghostwriter/psalm-sandbox\u0026logo=GitHub+Sponsors)](https://github.com/sponsors/ghostwriter)\n[![Automation](https://github.com/ghostwriter/psalm-sandbox/actions/workflows/automation.yml/badge.svg)](https://github.com/ghostwriter/psalm-sandbox/actions/workflows/automation.yml)\n[![Supported PHP Version](https://badgen.net/packagist/php/ghostwriter/psalm-sandbox?color=8892bf)](https://www.php.net/supported-versions)\n[![Downloads](https://badgen.net/packagist/dt/ghostwriter/psalm-sandbox?color=blue)](https://packagist.org/packages/ghostwriter/psalm-sandbox)\n\nwork in progress\n\n\u003e [!WARNING]\n\u003e\n\u003e This project is not finished yet, work in progress.\n\n## Installation\n\nYou can install the package via composer:\n\n``` bash\ncomposer require ghostwriter/psalm-sandbox --dev\n```\n\n## Usage\n\nYou can create a test for your plugin by extending the `AbstractPsalmSandboxTestCase` class.\n\neg. `tests/Unit/ExamplePluginTest.php`\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace Vendor\\PackageTests\\Unit;\n\nuse Ghostwriter\\PsalmSandbox\\AbstractPsalmSandboxTestCase;\nuse Psalm\\Issue\\CodeIssue;\nuse Psalm\\Issue\\MissingReturnType;\nuse Psalm\\Plugin\\PluginEntryPointInterface;\nuse Vendor\\Package\\ExamplePlugin;\n\nfinal class ExamplePluginTest extends AbstractPsalmSandboxTestCase\n{\n    /**\n     * @var class-string\u003cPluginEntryPointInterface\u003e\n     */\n    public const PLUGINS = [ExamplePlugin::class];\n\n    /**\n     * @var array\u003cclass-string\u003cCodeIssue\u003e\u003e\n     */\n    public const ISSUES = [MissingReturnType::class];\n}\n```\n\nYou can then run your tests using PHPUnit.\n\n``` bash\nvendor/bin/phpunit\n```\n\n## Plugin Development\n\n### Example Directory Structure\n\nYour plugin should have the following directory structure:\n\n``` text\ncomposer.json\nExamplePlugin.php\nsrc/\n│   {PsalmIssueType}/\n│   │   {FixIssue}.php\n│   │   {ReportIssue}.php\n│   │   {SuppressIssue}.php\n│   MissingReturnType/\n│   │   FixMissingReturnType.php\n│   │   ReportMissingReturnType.php\n│   │   SuppressMissingReturnType.php\ntests/\n│   Fixture/\n│   │   {PsalmIssueType}/\n│   │   │   fix-{PsalmIssueType}.php.inc\n│   │   │   report-{PsalmIssueType}.php.inc\n│   │   │   suppress-{PsalmIssueType}.php.inc\n│   │   MissingReturnType/\n│   │   │   fix-0001.php.inc\n│   │   │   fix-missing-returntype.php.inc\n│   │   │   report-0001.php.inc\n│   │   │   report-missing-returntype.php.inc\n│   │   │   suppress-0001.php.inc\n│   │   │   suppress-missing-returntype.php.inc\n│   Unit/\n│   │   ExamplePluginTest.php\n```\n\n### Example `Fix` Test\n\nWhen you run `vendor/bin/psalm --alter`, it will automatically fix the code for you.\n\nTo create a `Fix` test, you need to create a file in the `tests/Fixture/{PsalmIssueType}` directory.\n\nThe file name should be prefixed with `fix-` and any unique identifier, e.g. `fix-0001.php.inc`.\n\nThe file MUST use `--FIX--` to separate the `before` and `after` code.\n\nThe file should be structured as follows:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace Vendor\\PackageTests\\Fixture\\MissingReturnType;\n\nfinal class FixMissingReturnType\n{\n    public function fixMissingReturnType()\n    {\n    }\n}\n?\u003e\n--FIX--\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace Vendor\\PackageTests\\Fixture\\MissingReturnType;\n\nfinal class FixMissingReturnType\n{\n    public function fixMissingReturnType(): void\n    {\n    }\n}\n?\u003e\n```\n\n### Example `Report` Test\n\nWhen you run `vendor/bin/psalm`, it will report the issue in your code.\n\nTo create a `Report` test, you need to create a file in the `tests/Fixture/{PsalmIssueType}` directory.\n\nThe file name should be prefixed with `report-` and any unique identifier, e.g. `report-0001.php.inc`.\n\nThe file should be structured as follows:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace Vendor\\PackageTests\\Fixture\\MissingReturnType;\n\nfinal class ReportMissingReturnType\n{\n    public function reportMissingReturnType()\n    {\n    }\n}\n```\n\n### Example `Suppress` Test\n\nYou can suppress the issue in your code by adding the `@psalm-suppress` annotation, adding suppressions to your `psalm.xml` file, or using a plugin.\n\nTo create a `Suppress` test, you need to create a file in the `tests/Fixture/{PsalmIssueType}` directory.\n\nThe file name should be prefixed with `suppress-` and any unique identifier, e.g. `suppress-0001.php.inc`.\n\nThe file should be structured as follows:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace Vendor\\PackageTests\\Fixture\\MissingReturnType;\n\nfinal class SuppressMissingReturnType\n{\n    /**\n     * @psalm-suppress MissingReturnType\n     */\n    public function suppressMissingReturnType()\n    {\n    }\n}\n```\n\n## Testing\n\n``` bash\ncomposer test\n```\n\n## Changelog\n\nPlease see [CHANGELOG.md](./CHANGELOG.md) for more information what has changed recently.\n\n## Security\n\nIf you discover any security related issues, please email `nathanael.esayeas@protonmail.com` instead of using the issue tracker.\n\n## Support\n\n[[`Become a GitHub Sponsor`](https://github.com/sponsors/ghostwriter)]\n\n## Thank you\n\nTo acknowledge the efforts of those who create and maintain valuable projects for the community.\n\nThank you to [Bruce Weirdan](https://github.com/weirdan) for the original [`psalm/codeception-psalm-module`](https://github.com/psalm/codeception-psalm-module) that served as the starting point for my work.\n\nThank you to [Matt Brown](https://github.com/muglug), the creator of [`vimeo/psalm`](https://github.com/vimeo/psalm), a fantastic tool for static analysis in PHP.\n\nSpecial thanks to [@orklah](https://github.com/orklah) for maintaining [`vimeo/psalm`](https://github.com/vimeo/psalm), ensuring its continuous improvement and functionality.\n\n## Credits\n\n- [Nathanael Esayeas](https://github.com/ghostwriter)\n- [All Contributors](https://github.com/ghostwriter/psalm-sandbox/contributors)\n\n## License\n\nThe BSD-4-Clause. Please see [License File](./LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghostwriter%2Fpsalm-sandbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghostwriter%2Fpsalm-sandbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghostwriter%2Fpsalm-sandbox/lists"}