{"id":27899478,"url":"https://github.com/roave/infection-static-analysis-plugin","last_synced_at":"2025-12-29T12:11:44.446Z","repository":{"id":36957521,"uuid":"292340102","full_name":"Roave/infection-static-analysis-plugin","owner":"Roave","description":":white_check_mark: :dragon_face: Static analysis on top of mutation testing - prevents escaped mutants from being invalid according to static analysis","archived":false,"fork":false,"pushed_at":"2025-05-12T07:53:38.000Z","size":1446,"stargazers_count":124,"open_issues_count":13,"forks_count":19,"subscribers_count":7,"default_branch":"1.38.x","last_synced_at":"2025-05-13T16:53:31.550Z","etag":null,"topics":[],"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/Roave.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":"2020-09-02T16:47:15.000Z","updated_at":"2025-05-12T07:53:11.000Z","dependencies_parsed_at":"2024-03-08T06:23:43.415Z","dependency_job_id":"a1aa3345-0896-4155-8001-ae3bf6bd9030","html_url":"https://github.com/Roave/infection-static-analysis-plugin","commit_stats":{"total_commits":516,"total_committers":12,"mean_commits":43.0,"dds":0.624031007751938,"last_synced_commit":"23579f3f35262daa26ae3b2133212393f4bd8d36"},"previous_names":[],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roave%2Finfection-static-analysis-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roave%2Finfection-static-analysis-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roave%2Finfection-static-analysis-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roave%2Finfection-static-analysis-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Roave","download_url":"https://codeload.github.com/Roave/infection-static-analysis-plugin/tar.gz/refs/heads/1.38.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254337612,"owners_count":22054253,"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":[],"created_at":"2025-05-05T19:33:28.181Z","updated_at":"2025-12-29T12:11:44.414Z","avatar_url":"https://github.com/Roave.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Infection Static Analysis Plugin\n\nThis plugin is designed to run static analysis on top of [`infection/infection`](https://github.com/infection/infection)\ntest runs in order to discover if [escaped mutants](https://en.wikipedia.org/wiki/Mutation_testing)\nare valid mutations, or if they do not respect the type signature of your\nprogram. If the mutation would result in a type error, it is \"killed\".\n\nTL;DR:\n\n- This will improve your mutation score, since mutations which result in\n  type errors become killed.\n- This is very hacky, and replaces `vendor/bin/infection` essentially.\n  Please read the `Stability` section below first for details.\n- This is currently much slower than running infection by itself.\n  There are ideas/suggestions to improve this in the future.\n\n## Usage\n\nThe current design of this tool requires you to run `vendor/bin/roave-infection-static-analysis-plugin`\ninstead of running `vendor/bin/infection`:\n\n```sh\ncomposer require --dev roave/infection-static-analysis-plugin\n\nvendor/bin/roave-infection-static-analysis-plugin\n```\n\n### Configuration\n\nThe `roave-infection-static-analysis-plugin` binary accepts all of `infection` flags and arguments, and an additional `--psalm-config` argument.\n\nUsing `--psalm-config`, you can specify the psalm configuration file to use when analysing the generated mutations:\n\n```sh\nvendor/bin/roave-infection-static-analysis-plugin --psalm-config config/psalm.xml\n```\n\n## Background\n\nIf you come from a statically typed language with AoT compilers, you may be\nconfused about the scope of this project, but in the PHP ecosystem, producing\nrunnable code that does not respect the type system is very easy, and mutation\ntesting tools do this all the time.\n\nTake for example following snippet:\n\n```php\n/**\n * @template T\n * @param array\u003cT\u003e $values\n * @return list\u003cT\u003e\n */\nfunction makeAList(array $values): array\n{\n    return array_values($values);\n}\n```\n\nGiven a valid test as follows:\n\n```php\nfunction test_makes_a_list(): void\n{\n    $list = makeAList(['a' =\u003e 'b', 'c' =\u003e 'd']);\n \n    assert(count($list) === 2);\n    assert(in_array('b', $list, true));\n    assert(in_array('d', $list, true));\n}\n```\n\nThe mutation testing framework will produce following mutation, since we\nfailed to verify the output in a more precise way:\n\n```diff\n/**\n * @template T\n * @param array\u003cT\u003e $values\n * @return list\u003cT\u003e\n */\nfunction makeAList(array $values): array\n{\n-    return array_values($values);\n+    return $values;\n}\n```\n\nThe code above is valid PHP, but not valid according to our type declarations.\nWhile we can indeed write a test for this, such test would probably be\nunnecessary, as existing type checkers can detect that our actual return value is\nno longer a `list\u003cT\u003e`, but a map of `array\u003cint|string, T\u003e`, which is in conflict\nwith what we declared.\n\nThis plugin detects such mutations, and prevents them from making you write\nunnecessary tests, leveraging the full power of existing PHP type checkers\nsuch as [phpstan](https://github.com/phpstan/phpstan) and [psalm](https://github.com/vimeo/psalm).\n\n## Stability\n\nSince [`infection/infection`](https://github.com/infection/infection) is not yet\ndesigned to support plugins, this tool uses a very aggressive approach to bootstrap\nitself, and relies on internal details of the underlying runner.\n\nTo prevent compatibility issues, it therefore always pins to a very specific version\nof `infection/infection`, so please be patient when you wish to use the latest and\ngreatest version of `infection/infection`, as we may still be catching up to it.\n\nEventually, we will contribute patches to `infection/infection` so that there is a\nproper way to design and use plugins, without the need for dirty hacks.\n\n## PHPStan? Psalm? Where's my favourite static analysis tool?\n\nOur initial scope of work for `1.0.x` is to provide `vimeo/psalm` support as a start,\nwhile other static analysers will be included at a later point in time.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froave%2Finfection-static-analysis-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froave%2Finfection-static-analysis-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froave%2Finfection-static-analysis-plugin/lists"}