{"id":15014472,"url":"https://github.com/ta-tikoma/phpunit-architecture-test","last_synced_at":"2025-04-04T22:04:05.268Z","repository":{"id":57064390,"uuid":"420365180","full_name":"ta-tikoma/phpunit-architecture-test","owner":"ta-tikoma","description":"PHPUnit Application Architecture Test. For architecture tests","archived":false,"fork":false,"pushed_at":"2024-01-05T14:11:11.000Z","size":142,"stargazers_count":96,"open_issues_count":1,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-28T21:09:04.292Z","etag":null,"topics":["architecture","php","phpunit","test"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ta-tikoma.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}},"created_at":"2021-10-23T09:10:25.000Z","updated_at":"2025-03-27T11:56:16.000Z","dependencies_parsed_at":"2023-01-29T02:05:15.139Z","dependency_job_id":"bd9d47bd-17cb-45e0-947c-e46724abcadb","html_url":"https://github.com/ta-tikoma/phpunit-architecture-test","commit_stats":{"total_commits":87,"total_committers":4,"mean_commits":21.75,"dds":"0.22988505747126442","last_synced_commit":"d8616ea630cbbdfd2158973389eaba0b9c7dd4c8"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ta-tikoma%2Fphpunit-architecture-test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ta-tikoma%2Fphpunit-architecture-test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ta-tikoma%2Fphpunit-architecture-test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ta-tikoma%2Fphpunit-architecture-test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ta-tikoma","download_url":"https://codeload.github.com/ta-tikoma/phpunit-architecture-test/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247256107,"owners_count":20909240,"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":["architecture","php","phpunit","test"],"created_at":"2024-09-24T19:45:40.417Z","updated_at":"2025-04-04T22:04:05.246Z","avatar_url":"https://github.com/ta-tikoma.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PHPUnit Application Architecture Test\n\n**Idea**: write architecture tests as well as feature and unit tests. Protect your architecture code style!\n\n## Example\n\nDon't use repositories in controllers use only in services classes. Take three layers \"repositories\", \"services\", \"controllers\" and add asserts on dependencies.\n```php\n$controllers  = $this-\u003elayer()-\u003eleaveByNameStart('App\\\\Controllers');\n$services     = $this-\u003elayer()-\u003eleaveByNameStart('App\\\\Services');\n$repositories = $this-\u003elayer()-\u003eleaveByNameStart('App\\\\Repositories');\n\n$this-\u003eassertDoesNotDependOn($controllers, $repositories);\n$this-\u003eassertDependOn($controllers, $services);\n$this-\u003eassertDependOn($services, $repositories);\n```\n\n\n## Installation\n\n#### Install via composer\n\n```bash\ncomposer require --dev ta-tikoma/phpunit-architecture-test\n```\n\n#### Add trait to Test class\n\n```php\nabstract class TestCase extends BaseTestCase\n{\n    use ArchitectureAsserts;\n}\n```\n\n## Use\n\n- Create test\n- Make layers of application\n- Add asserts\n\n```php\n    public function test_make_layer_from_namespace()\n    {\n        $app = $this-\u003elayer()-\u003eleaveByNameStart('PHPUnit\\\\Architecture');\n        $tests = $this-\u003elayer()-\u003eleaveByNameStart('tests');\n\n        $this-\u003eassertDoesNotDependOn($app, $tests);\n        $this-\u003eassertDependOn($tests, $app);\n    }\n\n```\n\n#### Run\n```bash\n./vendor/bin/phpunit\n```\n\n## Test files structure\n\n- tests\n    - Architecture\n        - SomeTest.php\n    - Feature\n    - Unit\n\n## How to build Layer\n\n- `$this-\u003elayer()` take access to layer with all objects and filter for create your layer:\n    - leave objects in layer only:\n        - `-\u003eleave($closure)` by closure\n        - `-\u003eleaveByPathStart($path)` by object path start\n        - `-\u003eleaveByNameStart($name)` by object name start\n        - `-\u003eleaveByNameRegex($name)` by object name regex\n        - `-\u003eleaveByType($name)` by object type\n    - remove objects from layer:\n        - `-\u003eexclude($closure)` by closure\n        - `-\u003eexcludeByPathStart($path)` by object path start\n        - `-\u003eexcludeByNameStart($name)` by object name start\n        - `-\u003eexcludeByNameRegex($name)` by object name regex\n        - `-\u003eexcludeByType($name)` by object type\n- you can create multiple layers with split:\n    - `-\u003esplit($closure)` by closure\n    - `-\u003esplitByNameRegex($closure)` by object name\n\n\n## Asserts\n\n### Dependencies\n\n**Example:** Controllers don't use Repositories only via Services\n\n- `assertDependOn($A, $B)` Layer A must contains dependencies by layer B.\n- `assertDoesNotDependOn($A, $B)` Layer A (or layers in array A) must not contains dependencies by layer B (or layers in array B).\n\n### Methods \n\n- `assertIncomingsFrom($A, $B)` Layer A must contains arguments with types from Layer B\n- `assertIncomingsNotFrom($A, $B)` Layer A must not contains arguments with types from Layer B\n- `assertOutgoingFrom($A, $B)` Layer A must contains methods return types from Layer B\n- `assertOutgoingNotFrom($A, $B)` Layer A must not contains methods return types from Layer B\n- `assertMethodSizeLessThan($A, $SIZE)` Layer A must not contains methods with size less than SIZE\n\n### Properties\n\n- `assertHasNotPublicProperties($A)` Objects in Layer A must not contains public properties\n\n### Essence\n\nYou can use `$layer-\u003eessence($path)` method for collect data from layer. For example get visibility of all properties in layer: `$visibilities = $layer-\u003eessence('properties.*.visibility');` .\n\n- `assertEach($list, $check, $message)` - each item of list must passed tested by $check-function\n- `assertNotOne($list, $check, $message)` - not one item of list must not passed tested by $check-function\n- `assertAny($list, $check, $message)` - one or more item of list must not passed tested by $check-function\n\n## Alternatives\n- [Deptrac](https://github.com/qossmic/deptrac)\n- [PHP Architecture Tester](https://github.com/carlosas/phpat)\n- [PHPArch](https://github.com/j6s/phparch)\n- [Arkitect](https://github.com/phparkitect/arkitect)\n\n#### Advantages\n- Dynamic creation of layers by regular expression (not need declare each module)\n- Run along with the rest of tests from [phpunit](https://github.com/sebastianbergmann/phpunit)\n- Asserts to method arguments and return types (for check dependent injection)\n- Asserts to properties visibility\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fta-tikoma%2Fphpunit-architecture-test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fta-tikoma%2Fphpunit-architecture-test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fta-tikoma%2Fphpunit-architecture-test/lists"}