diff --git a/CHANGELOG.md b/CHANGELOG.md index fcd526f..689f72f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +- Mutation testing now counts code the tests execute but do not name in `#[Covers]` (`infection --threads=max --with-uncovered`); the `PublicVisibility` mutator is off and default values in parameter lists are ignored. No `src/` changes. + ## 0.3.0 — 2026-10-15 - Add `CompiledPipeline::call(..., ?Context $context)`: every layer obeys a `rasuvaeff/context` budget (#11). The context is checked before anything starts; retry runs `withContext()`; a `ContextAwareBulkhead` caps its slot wait by the budget; the callback receives the context (only when one is given). `fallback` is skipped only when this call's context is cancelled; its expiry, and everything without a context, still reach the fallback. `Rejection::is()` stays `false` for context exceptions. diff --git a/composer.json b/composer.json index 33c8918..ec29e2d 100644 --- a/composer.json +++ b/composer.json @@ -73,7 +73,10 @@ "cs": "php-cs-fixer fix --dry-run --diff --config=.php-cs-fixer.php", "cs:fix": "php-cs-fixer fix --diff --config=.php-cs-fixer.php", "docs": "php vendor/bin/doc-exec README.md README.ru.md", - "mutation": "infection --threads=max", + "mutation": [ + "Composer\\Config::disableProcessTimeout", + "infection --threads=max --with-uncovered" + ], "psalm": "psalm --no-cache", "rector": "rector process --dry-run", "rector:fix": "rector process", diff --git a/infection.json5 b/infection.json5 index 74ae281..4c042f7 100644 --- a/infection.json5 +++ b/infection.json5 @@ -10,6 +10,24 @@ "testFramework": "testo", "minMsi": 96, "mutators": { - "@default": true + "@default": true, + // Constructor/method parameter declarations with a default value + // (`private int $x = 100,`, `bool $strict = false,`): the mutant sits on a + // signature line with no executable opcode under pcov, so it is reported Not + // Covered whatever the tests do. Only a type-prefixed `$name = default,` line + // matches; a body line cannot (no type before the variable). Do NOT add ^ or $: + // Infection wraps the pattern as ^-\s*REGEX$ over the removed diff line. + // Verified 2026-11-01 by diffing the survivor lists with and without it: + // bulkhead 6, circuit-breaker 13, json-ld 19 mutants removed, all of them + // such signature lines; Escaped and Timed Out unchanged. + "global-ignoreSourceCodeByRegex": [ + "(?:(?:private|protected|public|readonly)\\s+)*\\??[A-Za-z_\\\\][\\w\\\\|]*\\s+\\$\\w+\\s*=\\s*[^,;]+," + ], + // Off: with --with-uncovered a PublicVisibility mutant sits on a parameterless + // method's signature line, which has no executable opcode under pcov/xdebug, + // so it is reported Not Covered and can never be killed, whatever #[Covers] + // says. Measured on pinned-http-client 2026-11-01: 4 of 4 such mutants were + // Not Covered, none killed. + "PublicVisibility": false } }