phpspec/prophecy
66.9
Adequate · 26 September 2026
7.7k
lines of production code
PHP
primary language
4
measurements over time
What this system is
This release modernizes the library for PHP 8.2+ and introduces extensive support for modern PHP type systems, including union, intersection, and standalone scalar types. The Prophecy component receives significant enhancements, featuring a comprehensive new argument matching API, improved double generation for final constructors and readonly classes, and updated exception handling. The test suite has been fully migrated to PHPSpec 4, and dependencies have been updated to support newer versions of key libraries.
Features
Add custom comparators for closures and Prophecy objects
The library now includes new comparator classes to handle comparison of PHP closures and Prophecy mock objects. Closures are compared by identity (two closures are considered equal only if they are the same instance), while Prophecy objects are compared by their revealed underlying objects. A new FactoryProvider class is introduced to manage these custom comparators, ensuring compatibility with both older and newer versions of the sebastian/comparator library.
src/Prophecy/Comparator · high confidence
New argument tokens for array, string, and logical matching
The library adds new argument-matching tokens to the \src/Prophecy/Argument/Token\ directory, including \ApproximateValueToken\, \ArrayCountToken\, \ArrayEntryToken\, \ArrayEveryEntryToken\, \IdenticalValueToken\, \InArrayToken\, \LogicalAndToken\, \LogicalNotToken\, \NotInArrayToken\, and \StringContainsToken\. These enable matching approximate numeric values, array sizes, specific key-value pairs, and logical combinations. The \CallbackToken\ is also updated to support a custom string representation, and \ExactValueToken\ is enhanced with a \ComparatorFactory\ to improve object comparison. Additionally, \TypeToken\ is fixed to correctly validate interfaces, and several existing token files have their namespace declarations corrected.
src/Prophecy/Argument/Token · high confidence
New internal tag retrievers for PHPDocumentor integration
Added three new internal classes—ClassAndInterfaceTagRetriever, ClassTagRetriever, and the MethodTagRetrieverInterface—to the Prophecy PhpDocumentor component. These new files implement a structured way to retrieve method tags from class and interface reflections, supporting the library's documentation generation capabilities.
src/Prophecy/PhpDocumentor · high confidence
Support for mocking classes with final constructors and passing constructor arguments
The library now allows mocking classes that have final constructors. To support this, the Doubler uses Doctrine's Instantiator to instantiate doubles when the constructor is not public or is final. Additionally, users can now pass constructor arguments to the Doubler via the new setArguments method on LazyDouble, which are then forwarded to the underlying double creation process.
src/Prophecy/Doubler · high confidence
Behavioural changes
Doubler exception classes updated with improved type hints and additional context
The exception classes in the Doubler namespace have been updated to include more specific type hints and docblocks. Specifically, the MethodNotFoundException now accepts and exposes the arguments used when the exception is thrown, allowing callers to inspect the method's arguments. Other exceptions like ClassMirrorException and ClassCreatorException now have more precise type hints for their properties (e.g., ReflectionClass\<object\>).
src/Prophecy/Exception/Doubler · medium confidence
Enhanced Call object with exception tracking and wildcard scoring
The Call object now tracks exceptions thrown during method execution and caches wildcard match scores for performance. CallCenter records exceptions in the Call object and re-throws them, while also supporting case-insensitive method name matching and caching argument wildcard scores to avoid redundant calculations.
src/Prophecy/Call · medium confidence
Enhanced exception handling and callback binding in promises
The promise classes in src/Prophecy/Promise have been updated to support modern PHP features and improve type safety. ThrowPromise now accepts any Throwable (not just Exception) and uses Doctrine's Instantiator for object construction, allowing more robust exception throwing. CallbackPromise's closure binding logic was refactored to use ReflectionFunction and Closure::bind more safely. ReturnArgumentPromise was extended to accept an optional index parameter, allowing users to return specific arguments by index rather than just the first one. Additionally, PHPDoc and type hints were updated across the board to reflect these changes.
src/Prophecy/Promise · medium confidence
Exception classes now support exception chaining
The Prophecy exception classes (ProphecyException, ObjectProphecyException, and MethodProphecyException) have been updated to accept a previous exception in their constructors. This allows developers to chain exceptions, preserving the full stack trace and context when errors occur during prophecy operations.
src/Prophecy/Exception/Prophecy · high confidence
Expanded argument matching API and improved prophecy creation
The Argument class now provides a comprehensive set of new static methods for matching arguments, including logical operators (allOf, not), array checks (size, withEntry, withEveryEntry, containing, withKey), string containment (containingString), identity checks (is), approximate value matching (approximate), and array inclusion checks (in, notIn). Additionally, the Prophet class now validates that a class or interface exists before attempting to prophesize it, throwing a ClassNotFoundException if the target cannot be found, and registers additional class patches for memory optimization and HHVM compatibility.
src/Prophecy · high confidence
Expose internal argument tokens via new getter
The ArgumentsWildcard class now exposes its internal $tokens array through a new public getTokens() method. This allows external code to inspect the list of Tokenackslash;TokenInterface objects stored within the wildcard, facilitating debugging or custom matching logic that requires access to the underlying token structure.
src/Prophecy/Argument · high confidence
Improved class double generation with stricter type handling and patch updates
The class double generation logic has been updated to handle several edge cases and improve type safety. The \DisableConstructorPatch\ now explicitly handles nullable and union types, and ensures constructors are only disabled if they are extendable. The \MagicCallPatch\ was refactored to use \ArgumentNode\ and \ReturnTypeNode\ instead of deprecated accessors, and now supports arguments on virtual magic methods. The \TraversablePatch\ now adds explicit return type hints (\mixed\, \void\, \bool\) to the generated \Iterator\ methods. A new \KeywordPatch\ was introduced to remove methods that clash with PHP keywords. Additionally, \ThrowablePatch\ was updated to allow doubling of classes that implement \Throwable\ by setting the parent class to \Exception\, and \ProphecySubjectPatch\ was updated to use \ArgumentTypeNode\ and \ObjectType\ for type hints.
src/Prophecy/Doubler/ClassPatch · high confidence
Improved error messages for prediction failures
Updated CallPrediction, CallTimesPrediction, NoCallsPrediction, and CallbackPrediction to provide more detailed and structured error messages when predictions fail. The changes include adding context about recorded calls, using consistent formatting with newlines and indentation, and leveraging StringUtil for call stringification. This makes debugging failed assertions easier by showing exactly which calls were recorded versus expected.
src/Prophecy/Prediction · high confidence
Improved object and string representation in Prophecy utilities
The Prophecy testing library's utility classes have been refactored to provide more readable and consistent string representations of objects and arrays. Object stringification now uses the stable \spl\_object\_id()\ instead of the volatile \spl\_object\_hash()\, and objects are formatted as \ClassName\#id\ rather than \ClassName:hash\. The \StringUtil::stringify()\ method now supports verbose mode, which truncates long strings and provides more detailed array formatting. A new \StringUtil::stringifyCalls()\ method was added to format arrays of Call objects for debugging. Additionally, a new \ExportUtil\ class was introduced to handle value exporting, mirroring the functionality of \sebastianbergmann/exporter\ with improvements such as rendering booleans as 'true'/'false' and normalizing newlines.
src/Prophecy/Util · high confidence
Improved return type handling and constructor argument support
Prophecy now automatically generates default return values for methods with supported return types (such as void, string, int, bool, array, callable, and objects), reducing the need for explicit configuration. It also enforces that final methods cannot be prophesied, throwing an exception instead. Additionally, ObjectProphecy now supports setting constructor arguments via a new willBeConstructedWith method, and the library has been updated to support PHP 8.1+ features including intersection and DNF return types.
src/Prophecy/Prophecy · high confidence
Modernized type hint handling and added support for readonly classes and return types
The code generator now uses a new \TypeNodeAbstract\-based system to handle type hints, enabling support for modern PHP features such as readonly classes, return types, and reference returns. The \ClassCodeGenerator\ now generates \readonly\ modifiers for classes and properly formats return type hints on methods. Additionally, the \ClassMirror\ reflects readonly status and tentatively defined return types, while the \TypeHintReference\ class is introduced to identify built-in types. These changes improve compatibility with newer PHP versions and provide more accurate code generation for class structures.
src/Prophecy/Doubler/Generator · medium confidence
Prophecy exceptions now implement the Throwable interface
The Prophecy exception classes have been updated to extend the native PHP \\\\Throwable interface. This behavioral change ensures that all Prophecy exceptions are compatible with modern PHP error handling, allowing them to be caught using standard try/catch blocks that handle \\\\Throwable.
src/Prophecy/Exception · high confidence
Refactored Prophecy prediction exception classes
The prediction exception classes in src/Prophecy/Exception/Prediction have been refactored to improve code quality and static analysis compatibility. This includes adding PHPDoc type hints (such as list\<PredictionException\> and list\<Call\>), moving namespace and use statements to the top of the files, and updating the formatting of the AggregateException message to remove leading whitespace. Additionally, several exception classes (FailedPredictionException, NoCallsException, PredictionException) were converted to single-line class definitions, and UnexpectedCallsCountException received updated type hints for its constructor parameters.
src/Prophecy/Exception/Prediction · medium confidence
Refactored type handling in the code generator to support modern PHP type syntax
The code generator's node classes have been refactored to use a new type system that supports PHP 8+ features like union types, intersection types, and standalone scalar types (true, false, null). This introduces new classes such as UnionType, IntersectionType, and ReturnTypeNode, allowing the generated doubles to correctly represent complex return and argument type hints. The change also deprecates the old string-based type hint methods in favor of the new type node API.
src/Prophecy/Doubler/Generator/Node · high confidence
UnexpectedCallException now exposes method arguments
The UnexpectedCallException class has been updated to include a new getArguments() method, allowing users to retrieve the array of arguments passed during an unexpected call. This change improves the exception's diagnostic value by exposing the call's arguments alongside the method name.
src/Prophecy/Exception/Call · high confidence
Update minimum PHP version to 8.2 and add support for PHP 8.5
The library now requires PHP 8.2 or higher, dropping support for earlier versions. It also adds support for PHP 8.5. Additionally, the project introduces a \.editorconfig\ file to enforce consistent coding styles, a \.gitattributes\ file to exclude development files from archives, and a \.php-cs-fixer.dist.php\ configuration for code style enforcement.
(repo-wide) · high confidence
Test coverage
Add comprehensive unit tests for ClassMirror; Add functional tests for double interface and case-insensitive method names; Add test coverage for FactoryProvider; Added specs for new and updated argument tokens; Added specs for type node refactoring and new type classes; Added test coverage for Prophecy comparators; Added tests for ExactValueToken; Added tests for MagicCallPatch; Added tests for TypeNodeAbstract null shorthand behavior; Expanded fixture coverage for modern PHP type system features; Updated Argument wildcard specs for PHP 7 compatibility; Updated Call and CallCenter specs for modern PHPSpec; Updated Prophecy Doubler specs for modern PhpSpec; Updated Prophecy argument and prophet specs for modern PHPSpec; Updated Prophecy doubler generator specs for modern PHP features; Updated Prophecy prediction exception specs for modern PHP; Updated Prophecy prediction specs for PhpSpec compatibility; Updated Prophecy specs for PhpSpec 4 and added test coverage for promise types; Updated Prophecy test suite for modern PHP and testing standards; Updated specs for PHP 8+ compatibility and added hash stringify tests; Updated test suite for class patches.
Dependencies
Update dependencies and modernize project configuration
The package now requires PHP 8.2 or higher and updates several core dependencies to support newer versions: phpdocumentor/reflection-docblock (^5.2 or ^6.0), sebastian/comparator (^3.0 through ^8.0), doctrine/instantiator (^1.2 or ^2.0), sebastian/recursion-context (^3.0 through ^8.0), and symfony/deprecation-contracts. Dev dependencies include php-cs-fixer/shim, phpspec, phpstan (^2.1.13, \<2.1.34 or ^2.1.39), and phpunit (^11.0 through ^13.0). The project also migrates from PSR-0 to PSR-4 autoloading, adds dev autoload namespaces, and introduces Composer scripts for coding standards and static analysis.
(dependencies) · medium confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 46 → 67 (+21.0)
- Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 97 → 96 (-0.5)
- Architecture 94 → 100 (+5.9)
- Maturity 59 → 55 (-4.5)
- Readiness 30 → 70 (+40.8)
- Security 45 → 75 (+29.9)
Resolved (19)
- Coverage not measured — test suite did not build
- Dimension evaluation failed
- Duplicated block (5 lines × 2) (spec/Prophecy/Prophecy/MethodProphecySpec.php)
- Duplicated block (5 lines × 2) (spec/Prophecy/Prophecy/MethodProphecySpec.php)
- Duplicated block (6 lines × 2) (spec/Prophecy/Argument/Token/ArrayEntryTokenSpec.php)
- Duplicated block (6 lines × 2) (spec/Prophecy/Doubler/CachedDoublerSpec.php)
- Duplicated block (6 lines × 2) (spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php)
- Duplicated block (7 lines × 2) (spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php)
- Duplicated block (7 lines × 2) (src/Prophecy/Doubler/ClassPatch/TraversablePatch.php)
- Duplicated block (7 lines × 4) (spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- No exposed public API
- No tests found
- Test reliability not included
New (50)
- ClassMirror.createTypeFromReflection (cognitive 23) (src/Prophecy/Doubler/Generator/ClassMirror.php)
- Dependency hygiene PARTLY measured — Composer dependencies read, no committed lock to grade for currency
- Documentation: no usage examples (README.md)
- Dormant codebase
- Duplicated block (5 lines × 2) (src/Prophecy/Argument/Token/ExactValueToken.php)
- Duplicated block (8 lines × 2) (src/Prophecy/Prediction/CallbackPrediction.php)
- ExactValueToken.scoreArgument (cognitive 18) (src/Prophecy/Argument/Token/ExactValueToken.php)
- ExportUtil.recursiveExport (cognitive 26) (src/Prophecy/Util/ExportUtil.php)
- ExportUtil.recursiveExport (cyclomatic 18) (src/Prophecy/Util/ExportUtil.php)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- Inverted test pyramid
- MagicCallPatch.apply (cognitive 40) (src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php)
- MethodProphecy.__construct (cognitive 29) (src/Prophecy/Prophecy/MethodProphecy.php)
- MethodProphecy.__construct (cyclomatic 34) (src/Prophecy/Prophecy/MethodProphecy.php)
- No dependency advisory monitoring
- …and 30 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
phpspec/prophecy was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 26 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 09c2e5949d676286358a62af818f8407167a9dd6 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-a15879f6f801.