|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This is the PHPStan extension for [Mockery](https://github.com/mockery/mockery), providing improved static analysis support for Mockery mock objects. |
| 4 | + |
| 5 | +## Project Goal |
| 6 | + |
| 7 | +This extension teaches PHPStan to understand Mockery's dynamic mock creation patterns so that static analysis works correctly with mocked objects. Without this extension, PHPStan cannot infer the correct types for mock objects created by Mockery. |
| 8 | + |
| 9 | +### Key features provided: |
| 10 | + |
| 11 | +- `Mockery::mock()` and `Mockery::spy()` return intersection types (e.g. `Foo&MockInterface`) so mocks can be used both as the mocked class and as a mock object |
| 12 | +- `Mockery::namedMock()` returns the same intersection types (skipping the first name argument) |
| 13 | +- `Foo|MockInterface` in phpDoc is interpreted as an intersection type instead of a union type (controlled by the `mockery.convertUnionToIntersectionType` parameter, enabled by default) |
| 14 | +- `shouldReceive()`, `allows()`, `expects()` and related expectation methods are understood on mock objects |
| 15 | +- Alias (`alias:`) and overload (`overload:`) mock prefixes are handled |
| 16 | +- Partial mock syntax (`ClassName[methodName]`) is supported |
| 17 | +- Multiple interfaces passed as comma-separated strings are resolved |
| 18 | +- Constructor argument arrays passed to `mock()` are handled correctly |
| 19 | + |
| 20 | +## Repository Structure |
| 21 | + |
| 22 | +``` |
| 23 | +src/ |
| 24 | + Mockery/ |
| 25 | + PhpDoc/ |
| 26 | + TypeNodeResolverExtension.php # Converts Foo|MockInterface union to intersection in phpDoc |
| 27 | + Reflection/ |
| 28 | + StubMethodReflection.php # Method reflection for stub interfaces (Allows/Expects) |
| 29 | + StubMethodsClassReflectionExtension.php # Makes any method callable on Allows/Expects interfaces |
| 30 | + Type/ |
| 31 | + Allows.php # Marker interface for allows() return type |
| 32 | + Expects.php # Marker interface for expects() return type |
| 33 | + MockDynamicReturnTypeExtension.php # Return types for Mockery::mock() and Mockery::spy() |
| 34 | + MockDynamicNamedMockReturnTypeExtension.php # Return types for Mockery::namedMock() |
| 35 | + StubDynamicReturnTypeExtension.php # Return types for allows() and expects() methods |
| 36 | +stubs/ |
| 37 | + MockInterface.stub # PHPStan stub for Mockery\MockInterface and LegacyMockInterface |
| 38 | +tests/ |
| 39 | + Mockery/ |
| 40 | + data/ # Test fixture classes (Foo, Bar, Baz, Buzz, etc.) |
| 41 | + MockeryTest.php # Tests for mock(), spy(), namedMock(), makePartial(), etc. |
| 42 | + MockeryBarTest.php # Tests for shouldReceive, expects, shouldHaveReceived, spies |
| 43 | + IsolatedMockeryTest.php # Tests for alias: and overload: mock prefixes |
| 44 | + DifferentNamespaceTest.php # Tests for mocks of classes in different namespaces |
| 45 | +extension.neon # PHPStan extension configuration (services, parameters, stubs) |
| 46 | +``` |
| 47 | + |
| 48 | +## PHP Version Support |
| 49 | + |
| 50 | +This repository supports **PHP 7.4+**. The `composer.json` platform is set to PHP 7.4.6. Do not use language features unavailable in PHP 7.4 (e.g. enums, fibers, readonly properties, intersection types in PHP syntax, first-class callable syntax). |
| 51 | + |
| 52 | +## Dependencies |
| 53 | + |
| 54 | +- `phpstan/phpstan`: ^2.0 |
| 55 | +- `mockery/mockery`: ^1.6.11 (dev) |
| 56 | +- `phpunit/phpunit`: ^9.6 (dev) |
| 57 | + |
| 58 | +## Development Commands |
| 59 | + |
| 60 | +All commands are defined in the `Makefile`: |
| 61 | + |
| 62 | +```bash |
| 63 | +# Run everything (lint, coding standard, tests, PHPStan analysis) |
| 64 | +make check |
| 65 | + |
| 66 | +# Run PHPUnit tests only |
| 67 | +make tests |
| 68 | + |
| 69 | +# Run PHP parallel lint on src/ and tests/ |
| 70 | +make lint |
| 71 | + |
| 72 | +# Run coding standard checks (requires build-cs to be installed first) |
| 73 | +make cs-install # Clone and install phpstan/build-cs (only needed once) |
| 74 | +make cs # Check coding standard |
| 75 | +make cs-fix # Auto-fix coding standard violations |
| 76 | + |
| 77 | +# Run PHPStan analysis at level 9 |
| 78 | +make phpstan |
| 79 | +``` |
| 80 | + |
| 81 | +## Coding Standard |
| 82 | + |
| 83 | +This project uses the [phpstan/build-cs](https://github.com/phpstan/build-cs) coding standard (branch `2.x`). The standard is applied via PHP_CodeSniffer with a configuration from the build-cs repository. |
| 84 | + |
| 85 | +Key style rules from `.editorconfig`: |
| 86 | +- Tabs for indentation in PHP, XML, and NEON files |
| 87 | +- Spaces for indentation in YAML files |
| 88 | +- UTF-8 charset, LF line endings, trailing whitespace trimmed, final newline inserted |
| 89 | + |
| 90 | +## Testing |
| 91 | + |
| 92 | +Tests use PHPUnit 9.6 and are located in `tests/Mockery/`. Test fixture classes live in `tests/Mockery/data/`. The bootstrap file is `tests/bootstrap.php` which loads the Composer autoloader. |
| 93 | + |
| 94 | +Tests are integration tests that create actual Mockery mocks and verify PHPStan correctly understands the types. Some tests extend `PHPUnit\Framework\TestCase`, others extend `Mockery\Adapter\Phpunit\MockeryTestCase`. |
| 95 | + |
| 96 | +## PHPStan Configuration |
| 97 | + |
| 98 | +- `extension.neon` — the extension's service definitions and parameters, shipped to users |
| 99 | +- `phpstan.neon` — project-level PHPStan configuration for self-analysis (level 9, includes strict-rules and phpunit extension, uses bleeding edge) |
| 100 | +- `phpstan-baseline.neon` — baseline for known issues in the test suite |
| 101 | + |
| 102 | +The extension registers services tagged with: |
| 103 | +- `phpstan.broker.dynamicStaticMethodReturnTypeExtension` — for `Mockery::mock()`, `Mockery::spy()`, `Mockery::namedMock()` |
| 104 | +- `phpstan.broker.dynamicMethodReturnTypeExtension` — for `allows()` and `expects()` on mock objects |
| 105 | +- `phpstan.broker.methodsClassReflectionExtension` — for the `Allows` and `Expects` stub interfaces |
| 106 | +- `phpstan.phpDoc.typeNodeResolverExtension` — for converting `Foo|MockInterface` unions to intersections |
| 107 | + |
| 108 | +## CI |
| 109 | + |
| 110 | +GitHub Actions workflow (`.github/workflows/build.yml`) runs on pushes to `2.0.x` and on pull requests. The matrix tests across PHP 7.4 through 8.5 with both lowest and highest dependency versions. |
| 111 | + |
| 112 | +CI jobs: |
| 113 | +1. **Lint** — `php-parallel-lint` across all PHP versions |
| 114 | +2. **Coding Standard** — phpcs with build-cs on PHP 8.2 |
| 115 | +3. **Tests** — PHPUnit across all PHP versions with lowest/highest dependencies |
| 116 | +4. **PHPStan** — self-analysis across all PHP versions with lowest/highest dependencies |
0 commit comments