diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 48b7890..fcd6af9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -295,6 +295,68 @@ jobs: - name: Install the engine from a dist archive and use it run: bin/consumer-smoke --only=core + adapters: + name: Adapter contract suite (${{ matrix.adapter }}) + # Keep this matrix unconditional. A matrix job skipped by its own `if:` + # reports one raw check name instead of the expanded names that branch + # protection requires, leaving each adapter context pending on docs-only + # changes. The four adapter suites are cheap compared with mutation. + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + adapter: + - testo + - psalm + - phpunit + - phpstan + + steps: + - name: Checkout core + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + path: core + + - name: Checkout adapter + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + repository: rasuvaeff/understudy-${{ matrix.adapter }} + persist-credentials: false + path: adapter + + - name: Setup PHP + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2 + with: + php-version: '8.4' + coverage: none + extensions: json, mbstring + tools: composer:v2 + + - name: Cache Composer dependencies + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.composer/cache + key: composer-${{ runner.os }}-${{ hashFiles('**/composer.json') }} + restore-keys: composer-${{ runner.os }}- + + - name: Point the adapter at this checkout of core + working-directory: adapter + run: | + composer config repositories.core '{"type":"path","url":"../core","options":{"versions":{"rasuvaeff/understudy":"1.0.0"}}}' + composer update --no-interaction --no-progress + + - name: Verify core resolved to the path repository + working-directory: adapter + run: | + composer show rasuvaeff/understudy | tee /tmp/core-source.txt + grep -qE '^path +: +' /tmp/core-source.txt + + - name: Adapter test suite + working-directory: adapter + run: composer test + coverage: name: Coverage & Mutation needs: changes diff --git a/README.md b/README.md index f60c684..e2e021d 100644 --- a/README.md +++ b/README.md @@ -69,30 +69,29 @@ here. Two rows are traps, marked ⚠. ## Performance -Against Mockery 1.6.15, Prophecy 1.26.1 and PHPUnit 12.5.33 on PHP 8.5.6. +Against Mockery 1.6.15, Prophecy 1.26.1 and PHPUnit 12.5.36 on PHP 8.5.6. Filtered means, three runs; understudy is the baseline. Full methodology, raw tables and the environment in [perf/README.md](perf/README.md). | | understudy | Mockery | Prophecy | PHPUnit | |---|---|---|---|---| -| build a double (1-method contract) | **2.06µs** | +216% | +683% | +155%¹ | -| build a double (8-method contract) | **2.06µs** | +217% | +641% | +158%¹ | -| stub: build, stub, one call, tear down | 10.6µs | +17% | +76% | **−17%**¹ | -| mock: build, expect, call, verify | 12.8µs | +4% | +128% | **−27%**² | -| marginal cost of one call to a stub | 0.86µs | 1.61µs | 1.51µs | **0.69µs**¹ | -| added to process start (cold) | **1.00×** | 1.50× | 4.96× | 5.38³ | -| retained per live double | **467–482 B** | 513 B | ~8.5 KB | ~1.25 KB | +| build a double (1-method contract) | **2.69µs** | +148% | +497% | +102%¹ | +| build a double (8-method contract) | **2.67µs** | +149% | +478% | +104%¹ | +| stub: build, stub, one call, tear down | 12.8µs | −8% | +33% | **−34%**¹ | +| mock: build, expect, call, verify | 16.0µs | −16% | +89% | **−41%**² | +| marginal cost of one call to a stub | 1.02µs | 1.62µs | 1.50µs | **0.70µs**¹ | +| added to process start (cold) | **1.00×** | 0.96× | 2.69× | 2.91³ | +| retained per live double | **571–586 B** | 513 B | ~8.5 KB | ~1.25 KB | ¹ `createStub()` ² `createMock()` ³ a ratio rather than milliseconds: cold start moves far more between runs than its ratios do. Understudy builds doubles about two and a half times cheaper than the next -fastest, and starts a process in a fifth of the added time. It does **not** win -everywhere: PHPUnit is ahead on both stub and mock scenarios end to end — it -dispatches a call in 0.69µs against understudy's 0.86µs and no longer pays -enough at build time to make up for it. +fastest. It does **not** win everywhere: PHPUnit is ahead on both stub and mock +scenarios end to end — it dispatches a call in 0.70µs against understudy's +1.02µs, and Mockery is marginally faster on cold start in this release run. -**Building a double costs more than it did**, 2.06µs against 1.28µs in the +**Building a double costs more than it did**, 2.69µs against 1.28µs in the figures published with 0.1.x. Those figures were taken at a commit *before* 0.1.0 and described no released version: a regression landed between them and the first tag, and has been shipping since. It is bisected and documented in diff --git a/README.ru.md b/README.ru.md index ceb4c0d..7290877 100644 --- a/README.ru.md +++ b/README.ru.md @@ -75,24 +75,24 @@ when(fn () => $repository->find(123))->returns($book); | | understudy | Mockery | Prophecy | PHPUnit | |---|---|---|---|---| -| создать дубль (контракт из 1 метода) | **2.06µs** | +216% | +683% | +155%¹ | -| создать дубль (контракт из 8 методов) | **2.06µs** | +217% | +641% | +158%¹ | -| stub: создать, застабить, вызвать, снести | 10.6µs | +17% | +76% | **−17%**¹ | -| mock: создать, expect, вызвать, verify | 12.8µs | +4% | +128% | **−27%**² | -| предельная цена одного вызова к стабу | 0.86µs | 1.61µs | 1.51µs | **0.69µs**¹ | -| добавляет к старту процесса (холодный) | **1.00×** | 1.50× | 4.96× | 5.38³ | -| удерживает на каждый живой дубль | **467–482 B** | 513 B | ~8.5 KB | ~1.25 KB | +| создать дубль (контракт из 1 метода) | **2.69µs** | +148% | +497% | +102%¹ | +| создать дубль (контракт из 8 методов) | **2.67µs** | +149% | +478% | +104%¹ | +| stub: создать, застабить, вызвать, снести | 12.8µs | −8% | +33% | **−34%**¹ | +| mock: создать, expect, вызвать, verify | 16.0µs | −16% | +89% | **−41%**² | +| предельная цена одного вызова к стабу | 1.02µs | 1.62µs | 1.50µs | **0.70µs**¹ | +| добавляет к старту процесса (холодный) | **1.00×** | 0.96× | 2.69× | 2.91³ | +| удерживает на каждый живой дубль | **571–586 B** | 513 B | ~8.5 KB | ~1.25 KB | ¹ `createStub()` ² `createMock()` ³ отношение, а не миллисекунды: холодный старт разбегается между прогонами куда сильнее, чем его отношения. -Understudy создаёт дубли примерно в два с половиной раза дешевле ближайшего и -добавляет к старту процесса впятеро меньше. Выигрывает он **не везде**: +Understudy создаёт дубли примерно в два с половиной раза дешевле ближайшего. +Выигрывает он **не везде**: PHPUnit впереди и на stub-, и на mock-сценарии целиком — он диспетчеризует -вызов за 0.69µs против 0.86µs у understudy и больше не платит на создании +вызов за 0.70µs против 1.02µs у understudy и больше не платит на создании столько, чтобы это перекрыть. -**Создание дубля стоит дороже, чем раньше** — 2.06µs против 1.28µs в цифрах, +**Создание дубля стоит дороже, чем раньше** — 2.69µs против 1.28µs в цифрах, опубликованных с 0.1.x. Те цифры сняты на коммите *до* 0.1.0 и не описывали ни одну выпущенную версию: между ними и первым тегом приехала регрессия, которая с тех пор и отгружается. Она локализована бисектом и описана в diff --git a/docs/.api-workspace/composer.json b/docs/.api-workspace/composer.json index a0ba909..6a0ef08 100644 --- a/docs/.api-workspace/composer.json +++ b/docs/.api-workspace/composer.json @@ -5,10 +5,10 @@ "require": { "php": "8.3 - 8.5", "phpdocumentor/reflection-docblock": "^5.6", - "rasuvaeff/understudy-phpstan": "^0.5", - "rasuvaeff/understudy-phpunit": "^0.5", - "rasuvaeff/understudy-psalm": "^0.8", - "rasuvaeff/understudy-testo": "^0.3" + "rasuvaeff/understudy-phpstan": "^1.0", + "rasuvaeff/understudy-phpunit": "^1.0", + "rasuvaeff/understudy-psalm": "^1.0", + "rasuvaeff/understudy-testo": "^1.0" }, "repositories": [ { @@ -16,7 +16,7 @@ "url": "../..", "options": { "versions": { - "rasuvaeff/understudy": "0.9.0" + "rasuvaeff/understudy": "1.0.0" } } } diff --git a/docs/.api-workspace/composer.lock b/docs/.api-workspace/composer.lock index 66c4583..93ec354 100644 --- a/docs/.api-workspace/composer.lock +++ b/docs/.api-workspace/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "059cd190a0914e592e82ce0d6034be72", + "content-hash": "582e42eedafa85deb76afbff89a7d61f", "packages": [ { "name": "amphp/amp", @@ -3096,11 +3096,11 @@ }, { "name": "rasuvaeff/understudy", - "version": "0.9.0", + "version": "1.0.0", "dist": { "type": "path", "url": "../..", - "reference": "5d86b82b1a030dcb58cfaf6633a08e09f35a7fe9" + "reference": "d044131323553ca7b6ecb639e9bb41d2ba10e1d7" }, "require": { "ext-tokenizer": "*", @@ -3234,23 +3234,23 @@ }, { "name": "rasuvaeff/understudy-phpstan", - "version": "v0.5.4", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/rasuvaeff/understudy-phpstan.git", - "reference": "6972d85231a6d889d25111b43e77873d0d688fc7" + "reference": "6d3fb1ca06d092dc613881efd6fe66bafa970914" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rasuvaeff/understudy-phpstan/zipball/6972d85231a6d889d25111b43e77873d0d688fc7", - "reference": "6972d85231a6d889d25111b43e77873d0d688fc7", + "url": "https://api.github.com/repos/rasuvaeff/understudy-phpstan/zipball/6d3fb1ca06d092dc613881efd6fe66bafa970914", + "reference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "shasum": "" }, "require": { "nikic/php-parser": "^5.0", "php": "8.3 - 8.5", "phpstan/phpstan": "^2.2.2", - "rasuvaeff/understudy": "^0.9 || ^0.10 || ^0.11 || ^0.12" + "rasuvaeff/understudy": "^1.0" }, "require-dev": { "ergebnis/composer-normalize": "^2.51", @@ -3302,26 +3302,26 @@ "issues": "https://github.com/rasuvaeff/understudy-phpstan/issues", "source": "https://github.com/rasuvaeff/understudy-phpstan" }, - "time": "2026-09-19T20:51:37+00:00" + "time": "2026-09-27T12:56:43+00:00" }, { "name": "rasuvaeff/understudy-phpunit", - "version": "v0.5.1", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/rasuvaeff/understudy-phpunit.git", - "reference": "36e8b245a647807301e2aeaff76ff89077fd8d30" + "reference": "3f415bfa3c0deaeb85f95c7be64ffd7e119bb509" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rasuvaeff/understudy-phpunit/zipball/36e8b245a647807301e2aeaff76ff89077fd8d30", - "reference": "36e8b245a647807301e2aeaff76ff89077fd8d30", + "url": "https://api.github.com/repos/rasuvaeff/understudy-phpunit/zipball/3f415bfa3c0deaeb85f95c7be64ffd7e119bb509", + "reference": "3f415bfa3c0deaeb85f95c7be64ffd7e119bb509", "shasum": "" }, "require": { "php": "8.3 - 8.5", "phpunit/phpunit": "^11.5 || ^12.0 || ^13.0", - "rasuvaeff/understudy": "^0.9 || ^0.10 || ^0.11 || ^0.12" + "rasuvaeff/understudy": "^1.0" }, "require-dev": { "ergebnis/composer-normalize": "^2.51", @@ -3366,26 +3366,26 @@ "issues": "https://github.com/rasuvaeff/understudy-phpunit/issues", "source": "https://github.com/rasuvaeff/understudy-phpunit" }, - "time": "2026-09-19T20:51:30+00:00" + "time": "2026-09-27T12:54:59+00:00" }, { "name": "rasuvaeff/understudy-psalm", - "version": "v0.8.5", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/rasuvaeff/understudy-psalm.git", - "reference": "c6ee952ae9b82840be30375d372422f79c723442" + "reference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rasuvaeff/understudy-psalm/zipball/c6ee952ae9b82840be30375d372422f79c723442", - "reference": "c6ee952ae9b82840be30375d372422f79c723442", + "url": "https://api.github.com/repos/rasuvaeff/understudy-psalm/zipball/94a16bb9675d36734e26a394f6aa54a142a2ccfc", + "reference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "shasum": "" }, "require": { "nikic/php-parser": "^5.0", "php": "8.3 - 8.5", - "rasuvaeff/understudy": "^0.9 || ^0.10 || ^0.11 || ^0.12", + "rasuvaeff/understudy": "^1.0", "vimeo/psalm": "^6.16" }, "require-dev": { @@ -3434,26 +3434,26 @@ "issues": "https://github.com/rasuvaeff/understudy-psalm/issues", "source": "https://github.com/rasuvaeff/understudy-psalm" }, - "time": "2026-09-19T20:51:23+00:00" + "time": "2026-09-27T12:53:25+00:00" }, { "name": "rasuvaeff/understudy-testo", - "version": "v0.3.5", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/rasuvaeff/understudy-testo.git", - "reference": "de861800cae579e91a901c87089e3a09d57c691d" + "reference": "e3d3087d4c68148a752549b8f378ea443cecda26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rasuvaeff/understudy-testo/zipball/de861800cae579e91a901c87089e3a09d57c691d", - "reference": "de861800cae579e91a901c87089e3a09d57c691d", + "url": "https://api.github.com/repos/rasuvaeff/understudy-testo/zipball/e3d3087d4c68148a752549b8f378ea443cecda26", + "reference": "e3d3087d4c68148a752549b8f378ea443cecda26", "shasum": "" }, "require": { "internal/container": "^1.0", "php": "8.3 - 8.5", - "rasuvaeff/understudy": "^0.9 || ^0.10 || ^0.11 || ^0.12", + "rasuvaeff/understudy": "^1.0", "testo/assert": "^0.1.13", "testo/testo": "^0.10.42" }, @@ -3499,7 +3499,7 @@ "issues": "https://github.com/rasuvaeff/understudy-testo/issues", "source": "https://github.com/rasuvaeff/understudy-testo" }, - "time": "2026-09-19T20:51:15+00:00" + "time": "2026-09-27T12:50:00+00:00" }, { "name": "revolt/event-loop", diff --git a/docs/scripts/api-snapshot.json b/docs/scripts/api-snapshot.json index 5ef45f8..1802338 100644 --- a/docs/scripts/api-snapshot.json +++ b/docs/scripts/api-snapshot.json @@ -2,7 +2,7 @@ "classes": [ { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Arg", "kind": "class", @@ -437,7 +437,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Bypass\\FileWrapper", "kind": "class", @@ -1099,7 +1099,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Bypass\\FinalStripper", "kind": "class", @@ -1159,7 +1159,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Captor", "kind": "class", @@ -1287,7 +1287,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Cardinality", "kind": "class", @@ -1480,7 +1480,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Codegen\\Blueprint", "kind": "class", @@ -1617,7 +1617,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Codegen\\DoubleFactory", "kind": "class", @@ -1660,7 +1660,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 27 + "startLine": 44 }, { "name": "instantiate", @@ -1683,7 +1683,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 48 + "startLine": 54 }, { "name": "blueprintFor", @@ -1706,7 +1706,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 59 + "startLine": 65 }, { "name": "blueprintOfGenerated", @@ -1729,7 +1729,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 80 + "startLine": 86 } ], "constants": [ @@ -1746,7 +1746,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Codegen\\MethodSignature", "kind": "class", @@ -1940,7 +1940,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Codegen\\PropertyDefaults", "kind": "class", @@ -1993,7 +1993,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Codegen\\PropertySignature", "kind": "class", @@ -2083,7 +2083,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Codegen\\TargetUnifier", "kind": "class", @@ -2136,7 +2136,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Codegen\\TypeRenderer", "kind": "class", @@ -2256,7 +2256,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Defaults\\DefaultFactories", "kind": "class", @@ -2361,7 +2361,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Defaults\\TypeDefaultResolver", "kind": "class", @@ -2500,7 +2500,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\AmbiguousDefaultFactory", "kind": "class", @@ -2560,7 +2560,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\BypassUnavailable", "kind": "class", @@ -2666,7 +2666,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\CannotWire", "kind": "class", @@ -2911,7 +2911,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\ConflictingExpectation", "kind": "class", @@ -3031,7 +3031,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\ContextOwnershipViolation", "kind": "class", @@ -3076,7 +3076,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\ForgottenDouble", "kind": "class", @@ -3121,6 +3121,29 @@ "attributes": [], "startLine": 23 }, + { + "name": "afterScope", + "static": true, + "params": [ + { + "name": "member", + "type": "non-empty-string", + "description": "the method called on the double, or the facade verb it was handed to", + "default": null, + "variadic": false + } + ], + "returnType": "Rasuvaeff\\Understudy\\Exception\\ForgottenDouble", + "summary": "The double was built inside `Understudy::scope()` and the scope has\nclosed since. There is no reset() to look for.", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 39 + }, { "name": "onPurpose", "static": true, @@ -3142,7 +3165,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 38 + "startLine": 54 }, { "name": "propertyAfterReset", @@ -3165,7 +3188,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 52 + "startLine": 68 }, { "name": "retired", @@ -3180,7 +3203,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 68 + "startLine": 84 }, { "name": "fromDefaultFactory", @@ -3203,7 +3226,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 82 + "startLine": 98 } ], "constants": [], @@ -3213,7 +3236,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\ForwardingTargetMismatch", "kind": "class", @@ -3303,7 +3326,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\InvalidCallSpecification", "kind": "class", @@ -3340,6 +3363,110 @@ "attributes": [], "startLine": 31 }, + { + "name": "moreThanOneCall", + "static": true, + "params": [ + { + "name": "firstLabel", + "type": "non-empty-string", + "description": "the double the first call was made on", + "default": null, + "variadic": false + }, + { + "name": "firstMethod", + "type": "non-empty-string", + "description": "the first call dispatched — for a nested pair, the inner one", + "default": null, + "variadic": false + }, + { + "name": "lastLabel", + "type": "non-empty-string", + "description": "the double the last call was made on", + "default": null, + "variadic": false + }, + { + "name": "lastMethod", + "type": "non-empty-string", + "description": "the last call dispatched — for a nested pair, the outer one", + "default": null, + "variadic": false + } + ], + "returnType": "Rasuvaeff\\Understudy\\Exception\\InvalidCallSpecification", + "summary": "The closure called more than one double method. Nested in the arguments\nof another (`find($r->count())`) or one after the other (`a() + b()`),\nthe recording cannot tell which one the test meant, and neither reading\nis safe to guess.", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 51 + }, + { + "name": "returnsOnVoid", + "static": true, + "params": [ + { + "name": "label", + "type": "non-empty-string", + "description": "the double, as a refusal names it", + "default": null, + "variadic": false + }, + { + "name": "method", + "type": "non-empty-string", + "description": "the method declared `: void`", + "default": null, + "variadic": false + } + ], + "returnType": "Rasuvaeff\\Understudy\\Exception\\InvalidCallSpecification", + "summary": "`returns()` on a method declared `: void`: the value would never be\nobserved, and a test that relies on it is checking nothing.", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 72 + }, + { + "name": "returnsOnNever", + "static": true, + "params": [ + { + "name": "label", + "type": "non-empty-string", + "description": "the double, as a refusal names it", + "default": null, + "variadic": false + }, + { + "name": "method", + "type": "non-empty-string", + "description": "the method declared `: never`", + "default": null, + "variadic": false + } + ], + "returnType": "Rasuvaeff\\Understudy\\Exception\\InvalidCallSpecification", + "summary": "`returns()` on a method declared `: never`, which cannot return at all.", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 89 + }, { "name": "notADouble", "static": true, @@ -3361,7 +3488,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 46 + "startLine": 106 }, { "name": "neverBesideACount", @@ -3384,7 +3511,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 62 + "startLine": 122 }, { "name": "exactCountBesideABound", @@ -3399,7 +3526,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 75 + "startLine": 135 }, { "name": "misplacedTailMatcher", @@ -3436,7 +3563,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 89 + "startLine": 149 }, { "name": "emptyCombinator", @@ -3459,7 +3586,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 106 + "startLine": 166 }, { "name": "tailMatcherInCombinator", @@ -3489,7 +3616,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 122 + "startLine": 182 }, { "name": "matcherInsideArray", @@ -3526,7 +3653,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 140 + "startLine": 200 }, { "name": "captorInCombinator", @@ -3549,7 +3676,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 158 + "startLine": 218 }, { "name": "emptySequence", @@ -3564,7 +3691,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 173 + "startLine": 233 }, { "name": "protocolAlreadyArmed", @@ -3594,7 +3721,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 187 + "startLine": 247 }, { "name": "incompleteSpecification", @@ -3631,7 +3758,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 205 + "startLine": 265 }, { "name": "omittedBeforeSpecified", @@ -3668,7 +3795,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 224 + "startLine": 284 }, { "name": "omittedTailNeedsRest", @@ -3698,7 +3825,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 242 + "startLine": 302 }, { "name": "closureFailed", @@ -3721,7 +3848,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 257 + "startLine": 317 }, { "name": "staticMethodCalled", @@ -3744,7 +3871,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 271 + "startLine": 331 } ], "constants": [], @@ -3754,7 +3881,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\InvalidDefaultValue", "kind": "class", @@ -3814,7 +3941,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\InvalidSpecificationArgument", "kind": "class", @@ -3941,6 +4068,50 @@ "attributes": [], "startLine": 73 }, + { + "name": "returnValueOfWrongType", + "static": true, + "params": [ + { + "name": "label", + "type": "non-empty-string", + "description": "the double, as a refusal names it", + "default": null, + "variadic": false + }, + { + "name": "method", + "type": "non-empty-string", + "description": "the method whose return type refused the value", + "default": null, + "variadic": false + }, + { + "name": "declared", + "type": "non-empty-string", + "description": "the return type as the contract declares it", + "default": null, + "variadic": false + }, + { + "name": "given", + "type": "non-empty-string", + "description": "the value's type, as `get_debug_type()` reports it", + "default": null, + "variadic": false + } + ], + "returnType": "Rasuvaeff\\Understudy\\Exception\\InvalidSpecificationArgument", + "summary": "A `returns()` value the declared return type cannot hold. Refused where\nit was written: left to the engine it surfaced as a `TypeError` naming\nthe generated class, from wherever in the code under test the call was.", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 88 + }, { "name": "unknownType", "static": true, @@ -3962,7 +4133,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 85 + "startLine": 106 }, { "name": "invertedBounds", @@ -3999,7 +4170,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 101 + "startLine": 122 }, { "name": "invalidPattern", @@ -4029,7 +4200,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 119 + "startLine": 140 } ], "constants": [], @@ -4039,7 +4210,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\MatcherLeaked", "kind": "class", @@ -4106,7 +4277,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\NeverMethodCalled", "kind": "class", @@ -4226,7 +4397,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\NoDefaultValue", "kind": "class", @@ -4293,7 +4464,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\NothingCaptured", "kind": "class", @@ -4346,7 +4517,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\OriginalCallUnavailable", "kind": "class", @@ -4429,7 +4600,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\OriginalReturnTypeViolation", "kind": "class", @@ -4496,7 +4667,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\OutcomeUnavailable", "kind": "class", @@ -4579,7 +4750,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\StrictModeViolation", "kind": "class", @@ -4646,7 +4817,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\UnderstudyError", "kind": "interface", @@ -4695,7 +4866,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\UnsupportedTarget", "kind": "class", @@ -4815,7 +4986,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Exception\\VerificationFailed", "kind": "class", @@ -4902,7 +5073,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\ExpectBuilder", "kind": "class", @@ -4950,7 +5121,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Expectation\\Action", "kind": "interface", @@ -5008,7 +5179,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Expectation\\ArgumentFormatter", "kind": "class", @@ -5091,7 +5262,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Expectation\\ComputeAnswer", "kind": "class", @@ -5158,7 +5329,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Expectation\\Expectation", "kind": "class", @@ -5616,7 +5787,97 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", + "rootReference": null, + "class": "Rasuvaeff\\Understudy\\Expectation\\ReturnContract", + "kind": "class", + "isApi": false, + "isAbstract": false, + "isThrowable": false, + "summary": "What a specified method may answer with, as `returns()` needs it: enough of\nthe signature to refuse a value the declared type cannot hold, and the\nnames a refusal has to carry.", + "description": "Checked at registration rather than at the call, because that is where the\nmistake was made. Left to the engine, the same value surfaced as a\n`TypeError` naming the generated class — `Understudy_a44bd4375e66f225::find()`\n— from wherever inside the code under test the call happened to be.", + "deprecated": null, + "see": [], + "extensionTags": { + "internal": [ + "" + ] + }, + "extends": null, + "implements": [], + "attributes": [], + "constructorParams": [ + { + "name": "label", + "type": "non-empty-string", + "description": "the double, as a refusal names it", + "default": null, + "promoted": true, + "promotedVisibility": "public", + "readonly": true + }, + { + "name": "method", + "type": "non-empty-string", + "description": "", + "default": null, + "promoted": true, + "promotedVisibility": "public", + "readonly": true + }, + { + "name": "signature", + "type": "Rasuvaeff\\Understudy\\Codegen\\MethodSignature", + "description": "", + "default": null, + "promoted": true, + "promotedVisibility": "public", + "readonly": true + }, + { + "name": "selfContract", + "type": "non-empty-string", + "description": "what `self` and `static` resolve to", + "default": null, + "promoted": true, + "promotedVisibility": "public", + "readonly": true + } + ], + "publicProperties": [], + "publicMethods": [ + { + "name": "accepts", + "static": false, + "params": [ + { + "name": "value", + "type": "mixed", + "description": "", + "default": null, + "variadic": false + } + ], + "returnType": "bool", + "summary": "Whether the declared return type can hold the value.", + "description": "Deliberately no stricter than the engine: a generated method is not\nunder `strict_types`, so a scalar declared type takes any scalar and a\n`string` takes a `Stringable` — `returns('5')` on `: int` answers `5`\ntoday and keeps doing so. What is refused is what PHP would refuse too:\n`null` where the type is not nullable, an array or an object where a\nscalar is declared, an object of the wrong class. A type this cannot\nread is accepted, so a wrong verdict here is impossible by construction.", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 46 + } + ], + "constants": [], + "enumCases": [], + "sourceUrl": "https://github.com/rasuvaeff/understudy/blob/master/src/Expectation/ReturnContract.php#L21", + "implementedBy": [] + }, + { + "root": "core", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Expectation\\ReturnValue", "kind": "class", @@ -5683,7 +5944,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Expectation\\ThrowComputed", "kind": "class", @@ -5750,7 +6011,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Expectation\\ThrowError", "kind": "class", @@ -5817,7 +6078,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\FailureKind", "kind": "enum", @@ -5906,7 +6167,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\FailureReport", "kind": "class", @@ -6091,7 +6352,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Invocation", "kind": "class", @@ -6484,7 +6745,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\AllOf", "kind": "class", @@ -6568,7 +6829,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\AnyArgument", "kind": "class", @@ -6642,7 +6903,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\AnyOf", "kind": "class", @@ -6726,7 +6987,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\AnyRest", "kind": "class", @@ -6826,7 +7087,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\AnyTail", "kind": "class", @@ -6926,7 +7187,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\ArgumentMatcher", "kind": "interface", @@ -7016,7 +7277,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\ArrayContaining", "kind": "class", @@ -7100,7 +7361,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\BooleanValue", "kind": "class", @@ -7174,7 +7435,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\Bounds", "kind": "class", @@ -7234,7 +7495,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\Capturing", "kind": "class", @@ -7327,7 +7588,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\CountBetween", "kind": "class", @@ -7420,7 +7681,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\EmptyTail", "kind": "class", @@ -7520,7 +7781,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\FloatInRange", "kind": "class", @@ -7613,7 +7874,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\IdenticalTo", "kind": "class", @@ -7697,7 +7958,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\InstanceOfType", "kind": "class", @@ -7781,7 +8042,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\IntInRange", "kind": "class", @@ -7874,7 +8135,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\Negated", "kind": "class", @@ -7958,7 +8219,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\Operand", "kind": "class", @@ -8041,7 +8302,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\QueryEquals", "kind": "class", @@ -8134,7 +8395,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\Satisfying", "kind": "class", @@ -8227,7 +8488,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\StringMatching", "kind": "class", @@ -8311,7 +8572,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\TailMatcher", "kind": "interface", @@ -8371,7 +8632,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\Unspelled", "kind": "class", @@ -8445,7 +8706,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Matcher\\UnspelledTail", "kind": "class", @@ -8545,7 +8806,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Outcome", "kind": "class", @@ -8717,8 +8978,8 @@ }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\ArgReturnType", "kind": "class", "isApi": false, @@ -8825,13 +9086,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/ArgReturnType.php#L40", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/ArgReturnType.php#L40", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\BuilderReturnType", "kind": "class", "isApi": false, @@ -8921,13 +9182,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/BuilderReturnType.php#L23", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/BuilderReturnType.php#L23", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\CaptorReturnType", "kind": "class", "isApi": false, @@ -9034,13 +9295,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/CaptorReturnType.php#L30", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/CaptorReturnType.php#L30", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Collector\\CaptureCallCollector", "kind": "class", "isApi": false, @@ -9118,13 +9379,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Collector/CaptureCallCollector.php#L27", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Collector/CaptureCallCollector.php#L27", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Collector\\HoistedMatcherCollector", "kind": "class", "isApi": false, @@ -9202,13 +9463,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Collector/HoistedMatcherCollector.php#L29", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Collector/HoistedMatcherCollector.php#L29", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Collector\\MatcherCallCollector", "kind": "class", "isApi": false, @@ -9286,13 +9547,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Collector/MatcherCallCollector.php#L20", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Collector/MatcherCallCollector.php#L20", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Collector\\SpecificationRangeCollector", "kind": "class", "isApi": false, @@ -9370,13 +9631,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Collector/SpecificationRangeCollector.php#L27", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Collector/SpecificationRangeCollector.php#L27", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\BuilderType", "kind": "class", "isApi": false, @@ -9437,13 +9698,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/BuilderType.php#L30", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/BuilderType.php#L30", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\Cardinality", "kind": "class", "isApi": false, @@ -9520,13 +9781,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/Cardinality.php#L16", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/Cardinality.php#L16", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\ClosureShape", "kind": "class", "isApi": false, @@ -9616,13 +9877,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/ClosureShape.php#L30", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/ClosureShape.php#L30", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\MatcherKind", "kind": "class", "isApi": false, @@ -9676,13 +9937,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/MatcherKind.php#L28", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/MatcherKind.php#L28", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\MatcherName", "kind": "class", "isApi": false, @@ -9729,13 +9990,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/MatcherName.php#L22", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/MatcherName.php#L22", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\ResolvedName", "kind": "class", "isApi": false, @@ -9782,13 +10043,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/ResolvedName.php#L20", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/ResolvedName.php#L20", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\SpecificationCheck", "kind": "class", "isApi": false, @@ -9868,13 +10129,13 @@ } ], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/SpecificationCheck.php#L35", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/SpecificationCheck.php#L35", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\SpecificationExpr", "kind": "class", "isApi": false, @@ -9921,13 +10182,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/SpecificationExpr.php#L22", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/SpecificationExpr.php#L22", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\SpecifiedCall", "kind": "class", "isApi": false, @@ -10039,13 +10300,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/SpecifiedCall.php#L32", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/SpecifiedCall.php#L32", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\VerbNames", "kind": "class", "isApi": false, @@ -10152,13 +10413,13 @@ } ], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/VerbNames.php#L16", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/VerbNames.php#L16", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Internal\\WireShape", "kind": "class", "isApi": false, @@ -10222,13 +10483,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/WireShape.php#L32", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/WireShape.php#L32", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\RestArity", "kind": "class", "isApi": false, @@ -10293,13 +10554,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/RestArity.php#L41", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/RestArity.php#L41", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Rule\\FluentCardinalityRule", "kind": "class", "isApi": false, @@ -10377,13 +10638,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Rule/FluentCardinalityRule.php#L28", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Rule/FluentCardinalityRule.php#L28", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Rule\\MatcherLeakRule", "kind": "class", "isApi": false, @@ -10468,13 +10729,13 @@ } ], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Rule/MatcherLeakRule.php#L35", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Rule/MatcherLeakRule.php#L35", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Rule\\SpecificationCallRule", "kind": "class", "isApi": false, @@ -10552,13 +10813,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Rule/SpecificationCallRule.php#L21", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Rule/SpecificationCallRule.php#L21", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Rule\\SpecificationStaticCallRule", "kind": "class", "isApi": false, @@ -10636,13 +10897,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Rule/SpecificationStaticCallRule.php#L23", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Rule/SpecificationStaticCallRule.php#L23", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\Rule\\VoidReturnsRule", "kind": "class", "isApi": false, @@ -10727,13 +10988,13 @@ } ], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Rule/VoidReturnsRule.php#L35", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Rule/VoidReturnsRule.php#L35", "implementedBy": [] }, { "root": "phpstan", - "rootVersion": "v0.5.2", - "rootReference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", + "rootVersion": "v1.0.0", + "rootReference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", "class": "Rasuvaeff\\Understudy\\PhpStan\\StaticBuilderReturnType", "kind": "class", "isApi": false, @@ -10850,13 +11111,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/StaticBuilderReturnType.php#L29", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/StaticBuilderReturnType.php#L29", "implementedBy": [] }, { "root": "phpunit", - "rootVersion": "v0.4.1", - "rootReference": "da80ba7a2f2290809b3191054e3a777d8ba02295", + "rootVersion": "v1.0.0", + "rootReference": "3f415bfa3c0deaeb85f95c7be64ffd7e119bb509", "class": "Rasuvaeff\\Understudy\\PhpUnit\\UnderstudyPHPUnitIntegration", "kind": "trait", "isApi": true, @@ -10879,13 +11140,80 @@ "publicMethods": [], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-phpunit/blob/da80ba7a2f2290809b3191054e3a777d8ba02295/src/PhpUnit/UnderstudyPHPUnitIntegration.php#L83", + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpunit/blob/3f415bfa3c0deaeb85f95c7be64ffd7e119bb509/src/PhpUnit/UnderstudyPHPUnitIntegration.php#L83", + "implementedBy": [] + }, + { + "root": "phpunit", + "rootVersion": "v1.0.0", + "rootReference": "3f415bfa3c0deaeb85f95c7be64ffd7e119bb509", + "class": "Rasuvaeff\\Understudy\\PhpUnit\\UnverifiedRun", + "kind": "class", + "isApi": false, + "isAbstract": false, + "isThrowable": false, + "summary": "The one decision the `#[After]` hook makes before resetting: did this test\npass, hold doubles, and never reach the trait's verification?", + "description": "A body that failed, errored, was skipped or marked incomplete never reached\n`assertPostConditions()` for a reason of its own, and PHPUnit already\nreports that reason; only a success — or a status nobody set, which is what\na test driven by hand outside the runner has — can hide a swallowed\nverification.", + "deprecated": null, + "see": [], + "extensionTags": { + "internal": [ + "" + ] + }, + "extends": null, + "implements": [], + "attributes": [], + "constructorParams": [], + "publicProperties": [], + "publicMethods": [ + { + "name": "detected", + "static": true, + "params": [ + { + "name": "verified", + "type": "bool", + "description": "", + "default": null, + "variadic": false + }, + { + "name": "status", + "type": "PHPUnit\\Framework\\TestStatus\\TestStatus", + "description": "", + "default": null, + "variadic": false + }, + { + "name": "idle", + "type": "bool", + "description": "", + "default": null, + "variadic": false + } + ], + "returnType": "bool", + "summary": "", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 23 + } + ], + "constants": [], + "enumCases": [], + "sourceUrl": "https://github.com/rasuvaeff/understudy-phpunit/blob/3f415bfa3c0deaeb85f95c7be64ffd7e119bb509/src/PhpUnit/UnverifiedRun.php#L21", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\BuilderReturnType", "kind": "class", "isApi": false, @@ -10953,13 +11281,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/BuilderReturnType.php#L19", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/BuilderReturnType.php#L19", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\CaptorRecorder", "kind": "class", "isApi": false, @@ -11027,13 +11355,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/CaptorRecorder.php#L39", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/CaptorRecorder.php#L39", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Internal\\BuilderType", "kind": "class", "isApi": false, @@ -11101,13 +11429,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Internal/BuilderType.php#L37", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Internal/BuilderType.php#L37", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Internal\\Cardinality", "kind": "class", "isApi": false, @@ -11184,13 +11512,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Internal/Cardinality.php#L16", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Internal/Cardinality.php#L16", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Internal\\ClosureShape", "kind": "class", "isApi": false, @@ -11280,13 +11608,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Internal/ClosureShape.php#L30", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Internal/ClosureShape.php#L30", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Internal\\MatcherClass", "kind": "class", "isApi": false, @@ -11333,13 +11661,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Internal/MatcherClass.php#L20", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Internal/MatcherClass.php#L20", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Internal\\MatcherKind", "kind": "class", "isApi": false, @@ -11393,13 +11721,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Internal/MatcherKind.php#L41", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Internal/MatcherKind.php#L41", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Internal\\ScopeIndex", "kind": "class", "isApi": false, @@ -11505,13 +11833,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Internal/ScopeIndex.php#L16", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Internal/ScopeIndex.php#L16", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Internal\\VerbNames", "kind": "class", "isApi": false, @@ -11595,13 +11923,13 @@ } ], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Internal/VerbNames.php#L17", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Internal/VerbNames.php#L17", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Internal\\WireShape", "kind": "class", "isApi": false, @@ -11655,13 +11983,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Internal/WireShape.php#L32", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Internal/WireShape.php#L32", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Issue\\UnderstudyMisuse", "kind": "class", "isApi": true, @@ -11680,13 +12008,13 @@ "publicMethods": [], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Issue/UnderstudyMisuse.php#L20", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Issue/UnderstudyMisuse.php#L20", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\MatcherArgument", "kind": "class", "isApi": false, @@ -11737,13 +12065,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/MatcherArgument.php#L34", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/MatcherArgument.php#L34", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\Plugin", "kind": "class", "isApi": true, @@ -11798,13 +12126,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Plugin.php#L18", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Plugin.php#L18", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\SpecificationRules", "kind": "class", "isApi": false, @@ -11855,13 +12183,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/SpecificationRules.php#L50", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/SpecificationRules.php#L50", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\SpecificationScope", "kind": "class", "isApi": false, @@ -11972,13 +12300,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/SpecificationScope.php#L31", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/SpecificationScope.php#L31", "implementedBy": [] }, { "root": "psalm", - "rootVersion": "v0.8.3", - "rootReference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", + "rootVersion": "v1.0.0", + "rootReference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", "class": "Rasuvaeff\\Understudy\\Psalm\\StaticBuilderReturnType", "kind": "class", "isApi": false, @@ -12046,12 +12374,12 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/StaticBuilderReturnType.php#L23", + "sourceUrl": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/StaticBuilderReturnType.php#L23", "implementedBy": [] }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Runtime\\Absent", "kind": "enum", @@ -12094,7 +12422,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Runtime\\ArmedSequence", "kind": "class", @@ -12300,7 +12628,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Runtime\\DoubleState", "kind": "class", @@ -12363,7 +12691,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 74 + "startLine": 77 }, { "name": "makeLean", @@ -12378,7 +12706,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 85 + "startLine": 88 }, { "name": "isLean", @@ -12393,7 +12721,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 90 + "startLine": 93 }, { "name": "setMode", @@ -12416,7 +12744,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 95 + "startLine": 98 }, { "name": "label", @@ -12431,7 +12759,30 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 103 + "startLine": 106 + }, + { + "name": "setDefaultLabel", + "static": false, + "params": [ + { + "name": "label", + "type": "non-empty-string", + "description": "", + "default": null, + "variadic": false + } + ], + "returnType": "void", + "summary": "The label a report uses when the test set none: the contract's short\nname, numbered by the owning context once it holds more than one double\nof that contract. An explicit `setLabel()` still outranks it.", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 118 }, { "name": "forwardingTarget", @@ -12446,7 +12797,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 114 + "startLine": 129 }, { "name": "setForwardingTarget", @@ -12469,7 +12820,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 119 + "startLine": 134 }, { "name": "setLabel", @@ -12492,7 +12843,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 127 + "startLine": 142 }, { "name": "writeProperty", @@ -12522,7 +12873,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 135 + "startLine": 150 }, { "name": "hasPropertyValue", @@ -12545,7 +12896,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 143 + "startLine": 158 }, { "name": "propertyValue", @@ -12568,7 +12919,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 151 + "startLine": 166 }, { "name": "referenceSlot", @@ -12605,7 +12956,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 165 + "startLine": 180 }, { "name": "hasActionFor", @@ -12635,7 +12986,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 187 + "startLine": 202 }, { "name": "addExpectation", @@ -12658,7 +13009,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 206 + "startLine": 221 }, { "name": "expectations", @@ -12673,7 +13024,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 278 + "startLine": 293 }, { "name": "expectationsFor", @@ -12703,7 +13054,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 296 + "startLine": 311 }, { "name": "declaredExpectations", @@ -12718,7 +13069,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 344 + "startLine": 359 }, { "name": "settle", @@ -12733,7 +13084,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 354 + "startLine": 369 }, { "name": "record", @@ -12756,7 +13107,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 383 + "startLine": 398 }, { "name": "callLog", @@ -12771,7 +13122,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 391 + "startLine": 406 } ], "constants": [], @@ -12781,7 +13132,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Runtime\\InvocationSignal", "kind": "class", @@ -12857,7 +13208,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Runtime\\Mode", "kind": "enum", @@ -12920,7 +13271,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Runtime\\ReferenceSlot", "kind": "class", @@ -12956,7 +13307,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Runtime\\Runtime", "kind": "class", @@ -12991,7 +13342,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 88 + "startLine": 98 }, { "name": "currentIfAny", @@ -13006,7 +13357,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 102 + "startLine": 112 }, { "name": "pushScope", @@ -13021,7 +13372,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 113 + "startLine": 123 }, { "name": "popScope", @@ -13036,7 +13387,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 121 + "startLine": 131 }, { "name": "adopt", @@ -13066,7 +13417,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 187 + "startLine": 197 }, { "name": "liveContexts", @@ -13081,7 +13432,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 221 + "startLine": 231 }, { "name": "adoptClone", @@ -13104,7 +13455,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 252 + "startLine": 262 }, { "name": "adoptInto", @@ -13134,7 +13485,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 280 + "startLine": 290 }, { "name": "adoptContractsInto", @@ -13164,7 +13515,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 292 + "startLine": 302 }, { "name": "ownerOf", @@ -13187,7 +13538,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 308 + "startLine": 318 }, { "name": "isForgotten", @@ -13210,7 +13561,60 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 322 + "startLine": 332 + }, + { + "name": "isDroppedByScope", + "static": true, + "params": [ + { + "name": "double", + "type": "object", + "description": "", + "default": null, + "variadic": false + } + ], + "returnType": "bool", + "summary": "Whether a double was forgotten by the `scope()` it was created in\nclosing, rather than by a `reset()`.", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 341 + }, + { + "name": "forgottenDouble", + "static": true, + "params": [ + { + "name": "double", + "type": "object", + "description": "", + "default": null, + "variadic": false + }, + { + "name": "member", + "type": "non-empty-string", + "description": "", + "default": null, + "variadic": false + } + ], + "returnType": "Rasuvaeff\\Understudy\\Exception\\ForgottenDouble", + "summary": "The refusal for a call or a question that reached a forgotten double,\nworded by what forgot it: `forget()`, a closing scope, or a reset.", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 352 }, { "name": "isRetiredOnPurpose", @@ -13233,7 +13637,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 330 + "startLine": 368 }, { "name": "forget", @@ -13256,7 +13660,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 342 + "startLine": 380 }, { "name": "stateOf", @@ -13279,7 +13683,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 405 + "startLine": 457 }, { "name": "isOwnedByCurrentContext", @@ -13302,7 +13706,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 410 + "startLine": 462 }, { "name": "dispatch", @@ -13339,7 +13743,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 423 + "startLine": 475 }, { "name": "propertyRead", @@ -13369,7 +13773,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 755 + "startLine": 827 }, { "name": "propertyWrite", @@ -13406,7 +13810,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 791 + "startLine": 863 }, { "name": "referenceSlot", @@ -13443,7 +13847,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 849 + "startLine": 921 }, { "name": "callOriginal", @@ -13480,7 +13884,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 889 + "startLine": 971 }, { "name": "reset", @@ -13495,7 +13899,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 1095 + "startLine": 1177 } ], "constants": [], @@ -13505,7 +13909,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Runtime\\RuntimeContext", "kind": "class", @@ -13547,7 +13951,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 59 + "startLine": 62 }, { "name": "arm", @@ -13570,7 +13974,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 64 + "startLine": 67 }, { "name": "disarm", @@ -13585,7 +13989,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 69 + "startLine": 72 }, { "name": "isRecording", @@ -13600,7 +14004,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 74 + "startLine": 77 }, { "name": "beginRecording", @@ -13615,7 +14019,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 79 + "startLine": 82 }, { "name": "endRecording", @@ -13630,7 +14034,45 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 84 + "startLine": 91 + }, + { + "name": "recordSpecificationCall", + "static": false, + "params": [ + { + "name": "signal", + "type": "Rasuvaeff\\Understudy\\Runtime\\InvocationSignal", + "description": "", + "default": null, + "variadic": false + } + ], + "returnType": "void", + "summary": "", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 98 + }, + { + "name": "recordingSignals", + "static": false, + "params": [], + "returnType": "array", + "summary": "", + "description": "", + "throws": [], + "throwsInBody": false, + "inheritedFrom": null, + "see": [], + "deprecated": null, + "attributes": [], + "startLine": 104 }, { "name": "register", @@ -13660,7 +14102,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 91 + "startLine": 109 }, { "name": "knows", @@ -13683,7 +14125,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 96 + "startLine": 136 }, { "name": "stateOf", @@ -13706,7 +14148,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 101 + "startLine": 141 }, { "name": "forget", @@ -13729,7 +14171,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 110 + "startLine": 150 }, { "name": "allStates", @@ -13744,7 +14186,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 118 + "startLine": 158 }, { "name": "allDoubles", @@ -13759,7 +14201,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 132 + "startLine": 172 }, { "name": "rememberCaptor", @@ -13782,7 +14224,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 152 + "startLine": 192 }, { "name": "captors", @@ -13797,7 +14239,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 168 + "startLine": 208 }, { "name": "nextSequence", @@ -13812,7 +14254,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 186 + "startLine": 226 }, { "name": "nextDeclaration", @@ -13827,7 +14269,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 198 + "startLine": 238 }, { "name": "globalLog", @@ -13842,7 +14284,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 210 + "startLine": 250 } ], "constants": [], @@ -13852,7 +14294,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Runtime\\SequenceVerdict", "kind": "enum", @@ -13925,8 +14367,8 @@ }, { "root": "testo", - "rootVersion": "v0.3.3", - "rootReference": "112422b07db04cf17d08f8a92664780e6bd476d2", + "rootVersion": "v1.0.0", + "rootReference": "e3d3087d4c68148a752549b8f378ea443cecda26", "class": "Rasuvaeff\\Understudy\\Testo\\UnderstudyInterceptor", "kind": "class", "isApi": true, @@ -13993,13 +14435,13 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-testo/blob/112422b07db04cf17d08f8a92664780e6bd476d2/src/Testo/UnderstudyInterceptor.php#L51", + "sourceUrl": "https://github.com/rasuvaeff/understudy-testo/blob/e3d3087d4c68148a752549b8f378ea443cecda26/src/Testo/UnderstudyInterceptor.php#L51", "implementedBy": [] }, { "root": "testo", - "rootVersion": "v0.3.3", - "rootReference": "112422b07db04cf17d08f8a92664780e6bd476d2", + "rootVersion": "v1.0.0", + "rootReference": "e3d3087d4c68148a752549b8f378ea443cecda26", "class": "Rasuvaeff\\Understudy\\Testo\\UnderstudyPlugin", "kind": "class", "isApi": true, @@ -14056,12 +14498,12 @@ ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy-testo/blob/112422b07db04cf17d08f8a92664780e6bd476d2/src/Testo/UnderstudyPlugin.php#L29", + "sourceUrl": "https://github.com/rasuvaeff/understudy-testo/blob/e3d3087d4c68148a752549b8f378ea443cecda26/src/Testo/UnderstudyPlugin.php#L29", "implementedBy": [] }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Understudy", "kind": "class", @@ -14107,7 +14549,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 62 + "startLine": 63 }, { "name": "when", @@ -14130,7 +14572,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 127 + "startLine": 128 }, { "name": "expect", @@ -14153,7 +14595,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 147 + "startLine": 148 }, { "name": "verifyAll", @@ -14176,7 +14618,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 168 + "startLine": 184 }, { "name": "verify", @@ -14227,7 +14669,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 419 + "startLine": 435 }, { "name": "calls", @@ -14250,7 +14692,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 503 + "startLine": 519 }, { "name": "lastCall", @@ -14273,7 +14715,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 525 + "startLine": 541 }, { "name": "strict", @@ -14296,7 +14738,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 555 + "startLine": 571 }, { "name": "lean", @@ -14319,7 +14761,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 580 + "startLine": 596 }, { "name": "forwarding", @@ -14349,7 +14791,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 598 + "startLine": 614 }, { "name": "delegate", @@ -14379,7 +14821,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 649 + "startLine": 665 }, { "name": "wire", @@ -14409,7 +14851,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 681 + "startLine": 697 }, { "name": "bypassFinals", @@ -14437,7 +14879,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 718 + "startLine": 734 }, { "name": "defaults", @@ -14467,7 +14909,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 803 + "startLine": 819 }, { "name": "label", @@ -14497,7 +14939,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 822 + "startLine": 838 }, { "name": "unused", @@ -14520,7 +14962,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 832 + "startLine": 848 }, { "name": "forget", @@ -14543,7 +14985,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 872 + "startLine": 888 }, { "name": "nothingElse", @@ -14573,7 +15015,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 892 + "startLine": 908 }, { "name": "allVerified", @@ -14596,7 +15038,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 935 + "startLine": 951 }, { "name": "expectSequence", @@ -14619,7 +15061,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 1018 + "startLine": 1034 }, { "name": "verifySequence", @@ -14642,7 +15084,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 1058 + "startLine": 1074 }, { "name": "transcript", @@ -14665,7 +15107,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 1084 + "startLine": 1100 }, { "name": "scope", @@ -14695,7 +15137,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 1220 + "startLine": 1236 }, { "name": "checkpoint", @@ -14718,7 +15160,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 1253 + "startLine": 1269 }, { "name": "reset", @@ -14733,7 +15175,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 1280 + "startLine": 1296 }, { "name": "idle", @@ -14748,17 +15190,17 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 1292 + "startLine": 1308 } ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy/blob/master/src/Understudy.php#L40", + "sourceUrl": "https://github.com/rasuvaeff/understudy/blob/master/src/Understudy.php#L41", "implementedBy": [] }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\VerificationFailure", "kind": "class", @@ -14865,7 +15307,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\WhenBuilder", "kind": "class", @@ -14893,6 +15335,15 @@ "promoted": true, "promotedVisibility": "protected", "readonly": true + }, + { + "name": "contract", + "type": "\\Rasuvaeff\\Understudy\\Expectation\\ReturnContract|null", + "description": "what the specified method may\nanswer with; `null` only where no signature is known", + "default": "NULL", + "promoted": true, + "promotedVisibility": "private", + "readonly": true } ], "publicProperties": [], @@ -14918,7 +15369,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 57 + "startLine": 66 }, { "name": "throws", @@ -14941,7 +15392,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 83 + "startLine": 117 }, { "name": "throwsWith", @@ -14964,7 +15415,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 108 + "startLine": 142 }, { "name": "answers", @@ -14987,7 +15438,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 120 + "startLine": 154 }, { "name": "then", @@ -15002,7 +15453,7 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 139 + "startLine": 173 }, { "name": "times", @@ -15032,17 +15483,17 @@ "see": [], "deprecated": null, "attributes": [], - "startLine": 156 + "startLine": 190 } ], "constants": [], "enumCases": [], - "sourceUrl": "https://github.com/rasuvaeff/understudy/blob/master/src/WhenBuilder.php#L37", + "sourceUrl": "https://github.com/rasuvaeff/understudy/blob/master/src/WhenBuilder.php#L39", "implementedBy": [] }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "class": "Rasuvaeff\\Understudy\\Wiring\\Wire", "kind": "class", @@ -15107,7 +15558,7 @@ "functions": [ { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "kind": "function", "function": "Rasuvaeff\\Understudy\\expect", @@ -15131,7 +15582,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "kind": "function", "function": "Rasuvaeff\\Understudy\\expectSequence", @@ -15155,7 +15606,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "kind": "function", "function": "Rasuvaeff\\Understudy\\verify", @@ -15207,7 +15658,7 @@ }, { "root": "core", - "rootVersion": "v0.10.0-2-g3cdc6e0", + "rootVersion": "v1.0.0", "rootReference": null, "kind": "function", "function": "Rasuvaeff\\Understudy\\when", diff --git a/docs/scripts/rules-snapshot.json b/docs/scripts/rules-snapshot.json index fd58ae6..0b75b7a 100644 --- a/docs/scripts/rules-snapshot.json +++ b/docs/scripts/rules-snapshot.json @@ -1,8 +1,8 @@ { "phpstan": { - "version": "v0.5.2", - "reference": "04cc11b417ff29a6877b0dd6cae345d4d7a4ba16", - "repoBlob": "https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/", + "version": "v1.0.0", + "reference": "6d3fb1ca06d092dc613881efd6fe66bafa970914", + "repoBlob": "https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/", "registeredRules": [ "Rasuvaeff\\Understudy\\PhpStan\\Rule\\SpecificationCallRule", "Rasuvaeff\\Understudy\\PhpStan\\Rule\\SpecificationStaticCallRule", @@ -49,9 +49,9 @@ ] }, "psalm": { - "version": "v0.8.3", - "reference": "adfcb7751dd3bc241d0cee864a6e3c47d19aca1a", - "repoBlob": "https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/", + "version": "v1.0.0", + "reference": "94a16bb9675d36734e26a394f6aa54a142a2ccfc", + "repoBlob": "https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/", "issues": [ { "issue": "UnderstudyMisuse", diff --git a/docs/src/api/classes/Arg.md b/docs/src/api/classes/Arg.md index 41d71ad..c2ad713 100644 --- a/docs/src/api/classes/Arg.md +++ b/docs/src/api/classes/Arg.md @@ -9,7 +9,7 @@ description: "Argument matchers, usable only inside a specification closure:" `Rasuvaeff\Understudy\Arg` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Arg.php#L50) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Arg.php#L50) — **Version:** v1.0.0 Argument matchers, usable only inside a specification closure: diff --git a/docs/src/api/classes/Captor.md b/docs/src/api/classes/Captor.md index fa84750..2c19a35 100644 --- a/docs/src/api/classes/Captor.md +++ b/docs/src/api/classes/Captor.md @@ -9,7 +9,7 @@ description: "A typed argument captor, built by Arg::captor()." `Rasuvaeff\Understudy\Captor` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Captor.php#L38) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Captor.php#L38) — **Version:** v1.0.0 **Type parameters:** diff --git a/docs/src/api/classes/Exception/AmbiguousDefaultFactory.md b/docs/src/api/classes/Exception/AmbiguousDefaultFactory.md index 83b6964..54e7321 100644 --- a/docs/src/api/classes/Exception/AmbiguousDefaultFactory.md +++ b/docs/src/api/classes/Exception/AmbiguousDefaultFactory.md @@ -9,7 +9,7 @@ description: "Two registered default factories are equally close to the requeste `Rasuvaeff\Understudy\Exception\AmbiguousDefaultFactory` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/AmbiguousDefaultFactory.php#L12) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/AmbiguousDefaultFactory.php#L12) — **Version:** v1.0.0 **Extends:** `LogicException` diff --git a/docs/src/api/classes/Exception/BypassUnavailable.md b/docs/src/api/classes/Exception/BypassUnavailable.md index 09b342e..48913b5 100644 --- a/docs/src/api/classes/Exception/BypassUnavailable.md +++ b/docs/src/api/classes/Exception/BypassUnavailable.md @@ -9,7 +9,7 @@ description: "`bypassFinals()` cannot do what was asked of it." `Rasuvaeff\Understudy\Exception\BypassUnavailable` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/BypassUnavailable.php#L12) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/BypassUnavailable.php#L12) — **Version:** v1.0.0 **Extends:** `LogicException` diff --git a/docs/src/api/classes/Exception/CannotWire.md b/docs/src/api/classes/Exception/CannotWire.md index 50c7ed3..33101e0 100644 --- a/docs/src/api/classes/Exception/CannotWire.md +++ b/docs/src/api/classes/Exception/CannotWire.md @@ -9,7 +9,7 @@ description: "`wire()` cannot build the subject, or cannot decide what to pass i `Rasuvaeff\Understudy\Exception\CannotWire` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/CannotWire.php#L12) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/CannotWire.php#L12) — **Version:** v1.0.0 **Extends:** `InvalidArgumentException` diff --git a/docs/src/api/classes/Exception/ConflictingExpectation.md b/docs/src/api/classes/Exception/ConflictingExpectation.md index d162e56..b0826df 100644 --- a/docs/src/api/classes/Exception/ConflictingExpectation.md +++ b/docs/src/api/classes/Exception/ConflictingExpectation.md @@ -9,7 +9,7 @@ description: "A `when()` or `expect()` names a call another registration already `Rasuvaeff\Understudy\Exception\ConflictingExpectation` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/ConflictingExpectation.php#L21) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/ConflictingExpectation.php#L21) — **Version:** v1.0.0 **Extends:** `LogicException` diff --git a/docs/src/api/classes/Exception/ContextOwnershipViolation.md b/docs/src/api/classes/Exception/ContextOwnershipViolation.md index 8d0b303..dd1e006 100644 --- a/docs/src/api/classes/Exception/ContextOwnershipViolation.md +++ b/docs/src/api/classes/Exception/ContextOwnershipViolation.md @@ -9,7 +9,7 @@ description: "Configuration and verification belong to the context that created `Rasuvaeff\Understudy\Exception\ContextOwnershipViolation` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/ContextOwnershipViolation.php#L14) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/ContextOwnershipViolation.php#L14) — **Version:** v1.0.0 **Extends:** `LogicException` diff --git a/docs/src/api/classes/Exception/ForgottenDouble.md b/docs/src/api/classes/Exception/ForgottenDouble.md index 11a01c6..1a889e5 100644 --- a/docs/src/api/classes/Exception/ForgottenDouble.md +++ b/docs/src/api/classes/Exception/ForgottenDouble.md @@ -9,7 +9,7 @@ description: "A double outlived the context that created it — almost always a `Rasuvaeff\Understudy\Exception\ForgottenDouble` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/ForgottenDouble.php#L16) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/ForgottenDouble.php#L16) — **Version:** v1.0.0 **Extends:** `LogicException` @@ -31,6 +31,17 @@ static afterReset(non-empty-string $method): Exception\ForgottenDouble Builds the error for calling a double after its context was reset. +### afterScope() + +```php +static afterScope(non-empty-string $member): Exception\ForgottenDouble +``` + +The double was built inside `Understudy::scope()` and the scope has +closed since. There is no reset() to look for. + +- `$member` — the method called on the double, or the facade verb it was handed to + ### onPurpose() ```php diff --git a/docs/src/api/classes/Exception/ForwardingTargetMismatch.md b/docs/src/api/classes/Exception/ForwardingTargetMismatch.md index 820b71b..45afafd 100644 --- a/docs/src/api/classes/Exception/ForwardingTargetMismatch.md +++ b/docs/src/api/classes/Exception/ForwardingTargetMismatch.md @@ -9,7 +9,7 @@ description: "The instance offered as a forwarding target does not satisfy what `Rasuvaeff\Understudy\Exception\ForwardingTargetMismatch` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/ForwardingTargetMismatch.php#L13) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/ForwardingTargetMismatch.php#L13) — **Version:** v1.0.0 **Extends:** `InvalidArgumentException` diff --git a/docs/src/api/classes/Exception/InvalidCallSpecification.md b/docs/src/api/classes/Exception/InvalidCallSpecification.md index cb5c3a1..9da7e5b 100644 --- a/docs/src/api/classes/Exception/InvalidCallSpecification.md +++ b/docs/src/api/classes/Exception/InvalidCallSpecification.md @@ -9,7 +9,7 @@ description: "A specification of the wrong SHAPE: the closure handed to when()/v `Rasuvaeff\Understudy\Exception\InvalidCallSpecification` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/InvalidCallSpecification.php#L25) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/InvalidCallSpecification.php#L25) — **Version:** v1.0.0 **Extends:** `LogicException` @@ -41,6 +41,56 @@ static noCallRecorded(): Exception\InvalidCallSpecification The closure ran to its end without any generated method signalling: it called nothing on a double, or only something that is not one. +### moreThanOneCall() + +```php +static moreThanOneCall( + non-empty-string $firstLabel, + non-empty-string $firstMethod, + non-empty-string $lastLabel, + non-empty-string $lastMethod, +): Exception\InvalidCallSpecification +``` + +The closure called more than one double method. Nested in the arguments +of another (`find($r->count())`) or one after the other (`a() + b()`), +the recording cannot tell which one the test meant, and neither reading +is safe to guess. + +- `$firstLabel` — the double the first call was made on +- `$firstMethod` — the first call dispatched — for a nested pair, the inner one +- `$lastLabel` — the double the last call was made on +- `$lastMethod` — the last call dispatched — for a nested pair, the outer one + +### returnsOnVoid() + +```php +static returnsOnVoid( + non-empty-string $label, + non-empty-string $method, +): Exception\InvalidCallSpecification +``` + +`returns()` on a method declared `: void`: the value would never be +observed, and a test that relies on it is checking nothing. + +- `$label` — the double, as a refusal names it +- `$method` — the method declared `: void` + +### returnsOnNever() + +```php +static returnsOnNever( + non-empty-string $label, + non-empty-string $method, +): Exception\InvalidCallSpecification +``` + +`returns()` on a method declared `: never`, which cannot return at all. + +- `$label` — the double, as a refusal names it +- `$method` — the method declared `: never` + ### notADouble() ```php diff --git a/docs/src/api/classes/Exception/InvalidDefaultValue.md b/docs/src/api/classes/Exception/InvalidDefaultValue.md index ea371dc..e25b40f 100644 --- a/docs/src/api/classes/Exception/InvalidDefaultValue.md +++ b/docs/src/api/classes/Exception/InvalidDefaultValue.md @@ -9,7 +9,7 @@ description: "A registered default factory produced a value the contract cannot `Rasuvaeff\Understudy\Exception\InvalidDefaultValue` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/InvalidDefaultValue.php#L12) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/InvalidDefaultValue.php#L12) — **Version:** v1.0.0 **Extends:** `RuntimeException` diff --git a/docs/src/api/classes/Exception/InvalidSpecificationArgument.md b/docs/src/api/classes/Exception/InvalidSpecificationArgument.md index c6d851b..f733376 100644 --- a/docs/src/api/classes/Exception/InvalidSpecificationArgument.md +++ b/docs/src/api/classes/Exception/InvalidSpecificationArgument.md @@ -9,7 +9,7 @@ description: "A VALUE inside a specification that no run could act on: a maximum `Rasuvaeff\Understudy\Exception\InvalidSpecificationArgument` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/InvalidSpecificationArgument.php#L24) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/InvalidSpecificationArgument.php#L24) — **Version:** v1.0.0 **Extends:** `InvalidArgumentException` @@ -81,6 +81,26 @@ static noReturnValues(): Exception\InvalidSpecificationArgument `returns()` with no arguments: there is nothing for the double to return, and the chain would answer the next call with nothing at all. +### returnValueOfWrongType() + +```php +static returnValueOfWrongType( + non-empty-string $label, + non-empty-string $method, + non-empty-string $declared, + non-empty-string $given, +): Exception\InvalidSpecificationArgument +``` + +A `returns()` value the declared return type cannot hold. Refused where +it was written: left to the engine it surfaced as a `TypeError` naming +the generated class, from wherever in the code under test the call was. + +- `$label` — the double, as a refusal names it +- `$method` — the method whose return type refused the value +- `$declared` — the return type as the contract declares it +- `$given` — the value's type, as `get_debug_type()` reports it + ### unknownType() ```php diff --git a/docs/src/api/classes/Exception/MatcherLeaked.md b/docs/src/api/classes/Exception/MatcherLeaked.md index 9892927..5694b58 100644 --- a/docs/src/api/classes/Exception/MatcherLeaked.md +++ b/docs/src/api/classes/Exception/MatcherLeaked.md @@ -9,7 +9,7 @@ description: "A matcher reached a real call instead of a specification closure." `Rasuvaeff\Understudy\Exception\MatcherLeaked` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/MatcherLeaked.php#L14) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/MatcherLeaked.php#L14) — **Version:** v1.0.0 **Extends:** `LogicException` diff --git a/docs/src/api/classes/Exception/NeverMethodCalled.md b/docs/src/api/classes/Exception/NeverMethodCalled.md index 53b7d9e..dea5b8a 100644 --- a/docs/src/api/classes/Exception/NeverMethodCalled.md +++ b/docs/src/api/classes/Exception/NeverMethodCalled.md @@ -9,7 +9,7 @@ description: "A method declared `: never` was called without an expectation that `Rasuvaeff\Understudy\Exception\NeverMethodCalled` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/NeverMethodCalled.php#L14) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/NeverMethodCalled.php#L14) — **Version:** v1.0.0 **Extends:** `RuntimeException` diff --git a/docs/src/api/classes/Exception/NoDefaultValue.md b/docs/src/api/classes/Exception/NoDefaultValue.md index 7583f2d..27ffd95 100644 --- a/docs/src/api/classes/Exception/NoDefaultValue.md +++ b/docs/src/api/classes/Exception/NoDefaultValue.md @@ -9,7 +9,7 @@ description: "A loose understudy had to answer a call, but the declared return t `Rasuvaeff\Understudy\Exception\NoDefaultValue` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/NoDefaultValue.php#L14) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/NoDefaultValue.php#L14) — **Version:** v1.0.0 **Extends:** `RuntimeException` diff --git a/docs/src/api/classes/Exception/NothingCaptured.md b/docs/src/api/classes/Exception/NothingCaptured.md index 99eb1f6..92be6ee 100644 --- a/docs/src/api/classes/Exception/NothingCaptured.md +++ b/docs/src/api/classes/Exception/NothingCaptured.md @@ -9,7 +9,7 @@ description: "`Captor::last()` was read before any matched call carried a value `Rasuvaeff\Understudy\Exception\NothingCaptured` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/NothingCaptured.php#L13) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/NothingCaptured.php#L13) — **Version:** v1.0.0 **Extends:** `LogicException` diff --git a/docs/src/api/classes/Exception/OriginalCallUnavailable.md b/docs/src/api/classes/Exception/OriginalCallUnavailable.md index a6e1786..b63aed0 100644 --- a/docs/src/api/classes/Exception/OriginalCallUnavailable.md +++ b/docs/src/api/classes/Exception/OriginalCallUnavailable.md @@ -9,7 +9,7 @@ description: "`callOriginal()` was asked to delegate, and there is nothing to de `Rasuvaeff\Understudy\Exception\OriginalCallUnavailable` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/OriginalCallUnavailable.php#L12) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/OriginalCallUnavailable.php#L12) — **Version:** v1.0.0 **Extends:** `LogicException` diff --git a/docs/src/api/classes/Exception/OriginalReturnTypeViolation.md b/docs/src/api/classes/Exception/OriginalReturnTypeViolation.md index 3d8f1c9..231d049 100644 --- a/docs/src/api/classes/Exception/OriginalReturnTypeViolation.md +++ b/docs/src/api/classes/Exception/OriginalReturnTypeViolation.md @@ -9,7 +9,7 @@ description: "A forwarded call returned an object the double cannot stand in for `Rasuvaeff\Understudy\Exception\OriginalReturnTypeViolation` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/OriginalReturnTypeViolation.php#L12) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/OriginalReturnTypeViolation.php#L12) — **Version:** v1.0.0 **Extends:** `RuntimeException` diff --git a/docs/src/api/classes/Exception/OutcomeUnavailable.md b/docs/src/api/classes/Exception/OutcomeUnavailable.md index 9144ae2..583ad54 100644 --- a/docs/src/api/classes/Exception/OutcomeUnavailable.md +++ b/docs/src/api/classes/Exception/OutcomeUnavailable.md @@ -9,7 +9,7 @@ description: "An invocation's outcome was read as the wrong kind: a returned val `Rasuvaeff\Understudy\Exception\OutcomeUnavailable` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/OutcomeUnavailable.php#L14) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/OutcomeUnavailable.php#L14) — **Version:** v1.0.0 **Extends:** `LogicException` diff --git a/docs/src/api/classes/Exception/StrictModeViolation.md b/docs/src/api/classes/Exception/StrictModeViolation.md index 97cb98f..1538940 100644 --- a/docs/src/api/classes/Exception/StrictModeViolation.md +++ b/docs/src/api/classes/Exception/StrictModeViolation.md @@ -9,7 +9,7 @@ description: "A strict understudy received a call no expectation matched." `Rasuvaeff\Understudy\Exception\StrictModeViolation` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/StrictModeViolation.php#L12) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/StrictModeViolation.php#L12) — **Version:** v1.0.0 **Extends:** `RuntimeException` diff --git a/docs/src/api/classes/Exception/UnderstudyError.md b/docs/src/api/classes/Exception/UnderstudyError.md index b63fada..288ed84 100644 --- a/docs/src/api/classes/Exception/UnderstudyError.md +++ b/docs/src/api/classes/Exception/UnderstudyError.md @@ -9,7 +9,7 @@ description: "Implemented by every exception this library throws, so a test can `Rasuvaeff\Understudy\Exception\UnderstudyError` -**Interface** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/UnderstudyError.php#L14) — **Version:** v0.10.0-2-g3cdc6e0 +**Interface** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/UnderstudyError.php#L14) — **Version:** v1.0.0 **Implements:** `Throwable`, `Stringable` diff --git a/docs/src/api/classes/Exception/UnsupportedTarget.md b/docs/src/api/classes/Exception/UnsupportedTarget.md index fd5a1d6..6a58b74 100644 --- a/docs/src/api/classes/Exception/UnsupportedTarget.md +++ b/docs/src/api/classes/Exception/UnsupportedTarget.md @@ -9,7 +9,7 @@ description: "The requested target cannot be doubled, and no option would make i `Rasuvaeff\Understudy\Exception\UnsupportedTarget` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/UnsupportedTarget.php#L13) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/UnsupportedTarget.php#L13) — **Version:** v1.0.0 **Extends:** `LogicException` diff --git a/docs/src/api/classes/Exception/VerificationFailed.md b/docs/src/api/classes/Exception/VerificationFailed.md index 5f1bd22..0e7a971 100644 --- a/docs/src/api/classes/Exception/VerificationFailed.md +++ b/docs/src/api/classes/Exception/VerificationFailed.md @@ -9,7 +9,7 @@ description: "A verification about what the code under test did (or did not) do `Rasuvaeff\Understudy\Exception\VerificationFailed` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/VerificationFailed.php#L20) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Exception/VerificationFailed.php#L20) — **Version:** v1.0.0 **Extends:** `RuntimeException` diff --git a/docs/src/api/classes/ExpectBuilder.md b/docs/src/api/classes/ExpectBuilder.md index a2f5653..2039729 100644 --- a/docs/src/api/classes/ExpectBuilder.md +++ b/docs/src/api/classes/ExpectBuilder.md @@ -9,7 +9,7 @@ description: "Configures a call the code under test is expected to make." `Rasuvaeff\Understudy\ExpectBuilder` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/ExpectBuilder.php#L19) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/ExpectBuilder.php#L19) — **Version:** v1.0.0 **Extends:** [`WhenBuilder`](/api/classes/WhenBuilder) diff --git a/docs/src/api/classes/FailureKind.md b/docs/src/api/classes/FailureKind.md index dd5a622..d18dcb8 100644 --- a/docs/src/api/classes/FailureKind.md +++ b/docs/src/api/classes/FailureKind.md @@ -9,7 +9,7 @@ description: "What kind of verification claim a VerificationFailure reports." `Rasuvaeff\Understudy\FailureKind` -**Enum** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/FailureKind.php#L12) — **Version:** v0.10.0-2-g3cdc6e0 +**Enum** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/FailureKind.php#L12) — **Version:** v1.0.0 **Implements:** `UnitEnum` diff --git a/docs/src/api/classes/Invocation.md b/docs/src/api/classes/Invocation.md index e9b342e..8b0048f 100644 --- a/docs/src/api/classes/Invocation.md +++ b/docs/src/api/classes/Invocation.md @@ -9,7 +9,7 @@ description: "One recorded call on an understudy." `Rasuvaeff\Understudy\Invocation` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Invocation.php#L21) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Invocation.php#L21) — **Version:** v1.0.0 One recorded call on an understudy. diff --git a/docs/src/api/classes/PhpUnit/UnderstudyPHPUnitIntegration.md b/docs/src/api/classes/PhpUnit/UnderstudyPHPUnitIntegration.md index 237c051..d6d0283 100644 --- a/docs/src/api/classes/PhpUnit/UnderstudyPHPUnitIntegration.md +++ b/docs/src/api/classes/PhpUnit/UnderstudyPHPUnitIntegration.md @@ -9,7 +9,7 @@ description: "Ends every PHPUnit test with understudy's own bookkeeping done for `Rasuvaeff\Understudy\PhpUnit\UnderstudyPHPUnitIntegration` -**Trait** — **Package:** [rasuvaeff/understudy-phpunit](https://github.com/rasuvaeff/understudy-phpunit) — [Source](https://github.com/rasuvaeff/understudy-phpunit/blob/da80ba7a2f2290809b3191054e3a777d8ba02295/src/PhpUnit/UnderstudyPHPUnitIntegration.php#L83) — **Version:** v0.4.1 +**Trait** — **Package:** [rasuvaeff/understudy-phpunit](https://github.com/rasuvaeff/understudy-phpunit) — [Source](https://github.com/rasuvaeff/understudy-phpunit/blob/3f415bfa3c0deaeb85f95c7be64ffd7e119bb509/src/PhpUnit/UnderstudyPHPUnitIntegration.php#L83) — **Version:** v1.0.0 Ends every PHPUnit test with understudy's own bookkeeping done for it. diff --git a/docs/src/api/classes/Psalm/Issue/UnderstudyMisuse.md b/docs/src/api/classes/Psalm/Issue/UnderstudyMisuse.md index 96d2187..ee3bac8 100644 --- a/docs/src/api/classes/Psalm/Issue/UnderstudyMisuse.md +++ b/docs/src/api/classes/Psalm/Issue/UnderstudyMisuse.md @@ -9,7 +9,7 @@ description: "A specification that cannot mean what it says." `Rasuvaeff\Understudy\Psalm\Issue\UnderstudyMisuse` -**Class** — **Package:** [rasuvaeff/understudy-psalm](https://github.com/rasuvaeff/understudy-psalm) — [Source](https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Issue/UnderstudyMisuse.php#L20) — **Version:** v0.8.3 +**Class** — **Package:** [rasuvaeff/understudy-psalm](https://github.com/rasuvaeff/understudy-psalm) — [Source](https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Issue/UnderstudyMisuse.php#L20) — **Version:** v1.0.0 **Extends:** `Psalm\Issue\PluginIssue` diff --git a/docs/src/api/classes/Psalm/Plugin.md b/docs/src/api/classes/Psalm/Plugin.md index 3c83a08..eb0ec29 100644 --- a/docs/src/api/classes/Psalm/Plugin.md +++ b/docs/src/api/classes/Psalm/Plugin.md @@ -9,7 +9,7 @@ description: "Entry point registered through `extra.psalm.pluginClass`, so `vend `Rasuvaeff\Understudy\Psalm\Plugin` -**Class** — **Package:** [rasuvaeff/understudy-psalm](https://github.com/rasuvaeff/understudy-psalm) — [Source](https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Plugin.php#L18) — **Version:** v0.8.3 +**Class** — **Package:** [rasuvaeff/understudy-psalm](https://github.com/rasuvaeff/understudy-psalm) — [Source](https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Plugin.php#L18) — **Version:** v1.0.0 **Implements:** `Psalm\Plugin\PluginEntryPointInterface`, `Psalm\Plugin\PluginInterface` diff --git a/docs/src/api/classes/Testo/UnderstudyInterceptor.md b/docs/src/api/classes/Testo/UnderstudyInterceptor.md index d15afdf..b3c9d1e 100644 --- a/docs/src/api/classes/Testo/UnderstudyInterceptor.md +++ b/docs/src/api/classes/Testo/UnderstudyInterceptor.md @@ -9,7 +9,7 @@ description: "Ends every test with understudy's own bookkeeping done for it." `Rasuvaeff\Understudy\Testo\UnderstudyInterceptor` -**Class** — **Package:** [rasuvaeff/understudy-testo](https://github.com/rasuvaeff/understudy-testo) — [Source](https://github.com/rasuvaeff/understudy-testo/blob/112422b07db04cf17d08f8a92664780e6bd476d2/src/Testo/UnderstudyInterceptor.php#L51) — **Version:** v0.3.3 +**Class** — **Package:** [rasuvaeff/understudy-testo](https://github.com/rasuvaeff/understudy-testo) — [Source](https://github.com/rasuvaeff/understudy-testo/blob/e3d3087d4c68148a752549b8f378ea443cecda26/src/Testo/UnderstudyInterceptor.php#L51) — **Version:** v1.0.0 **Implements:** `Testo\Pipeline\Middleware\TestRunInterceptor`, `Testo\Pipeline\Interceptor` diff --git a/docs/src/api/classes/Testo/UnderstudyPlugin.md b/docs/src/api/classes/Testo/UnderstudyPlugin.md index c21166b..1cd9d6d 100644 --- a/docs/src/api/classes/Testo/UnderstudyPlugin.md +++ b/docs/src/api/classes/Testo/UnderstudyPlugin.md @@ -9,7 +9,7 @@ description: "Registers UnderstudyInterceptor so every test of the suite ends wi `Rasuvaeff\Understudy\Testo\UnderstudyPlugin` -**Class** — **Package:** [rasuvaeff/understudy-testo](https://github.com/rasuvaeff/understudy-testo) — [Source](https://github.com/rasuvaeff/understudy-testo/blob/112422b07db04cf17d08f8a92664780e6bd476d2/src/Testo/UnderstudyPlugin.php#L29) — **Version:** v0.3.3 +**Class** — **Package:** [rasuvaeff/understudy-testo](https://github.com/rasuvaeff/understudy-testo) — [Source](https://github.com/rasuvaeff/understudy-testo/blob/e3d3087d4c68148a752549b8f378ea443cecda26/src/Testo/UnderstudyPlugin.php#L29) — **Version:** v1.0.0 **Implements:** `Testo\Common\PluginConfigurator` diff --git a/docs/src/api/classes/Understudy.md b/docs/src/api/classes/Understudy.md index fba9527..fe7bf3d 100644 --- a/docs/src/api/classes/Understudy.md +++ b/docs/src/api/classes/Understudy.md @@ -9,7 +9,7 @@ description: "The whole public surface, as static methods so that an understudy `Rasuvaeff\Understudy\Understudy` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Understudy.php#L40) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/Understudy.php#L41) — **Version:** v1.0.0 The whole public surface, as static methods so that an understudy itself can stay free of service members: every one of them would be a name the doubled diff --git a/docs/src/api/classes/VerificationFailure.md b/docs/src/api/classes/VerificationFailure.md index 7829f5c..c126c57 100644 --- a/docs/src/api/classes/VerificationFailure.md +++ b/docs/src/api/classes/VerificationFailure.md @@ -9,7 +9,7 @@ description: "The structured half of one verification failure — the same facts `Rasuvaeff\Understudy\VerificationFailure` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/VerificationFailure.php#L34) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/VerificationFailure.php#L34) — **Version:** v1.0.0 The structured half of one verification failure — the same facts the rendered message states, addressable by field. diff --git a/docs/src/api/classes/WhenBuilder.md b/docs/src/api/classes/WhenBuilder.md index f1234f6..01203ac 100644 --- a/docs/src/api/classes/WhenBuilder.md +++ b/docs/src/api/classes/WhenBuilder.md @@ -9,7 +9,7 @@ description: "Configures what a stubbed call does." `Rasuvaeff\Understudy\WhenBuilder` -**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/WhenBuilder.php#L37) — **Version:** v0.10.0-2-g3cdc6e0 +**Class** — **Package:** [rasuvaeff/understudy](https://github.com/rasuvaeff/understudy) — [Source](https://github.com/rasuvaeff/understudy/blob/master/src/WhenBuilder.php#L39) — **Version:** v1.0.0 **Type parameters:** @@ -38,12 +38,14 @@ class would mean duplicating every action verb on `ExpectBuilder` — and a ```php __construct( Expectation\Expectation $expectation, + \Expectation\ReturnContract|null $contract = NULL, ) ``` | Parameter | Type | Default | Description | |---|---|---|---| | `$expectation` | `Expectation\Expectation` | *required* | | +| `$contract` | `\Expectation\ReturnContract\|null` | `NULL` | what the specified method may answer with; `null` only where no signature is known | ## Methods diff --git a/docs/src/api/rules.md b/docs/src/api/rules.md index fdcf8c4..1b8ce63 100644 --- a/docs/src/api/rules.md +++ b/docs/src/api/rules.md @@ -9,15 +9,15 @@ description: "Every identifier the PHPStan extension reports and every issue typ Neither analyser package has an `@api` class, and that is correct rather than a missing annotation: `understudy-phpstan` is registered through `extension.neon` and `understudy-psalm` through `psalm-plugin enable`, so a user never names one of their classes. What a user does write is an **identifier**, in `ignoreErrors` or a suppression. That is the contract, so that is what is reflected here. -## PHPStan · `rasuvaeff/understudy-phpstan` v0.5.2 +## PHPStan · `rasuvaeff/understudy-phpstan` v1.0.0 | Identifier | Reported by | Summary | |---|---|---| -| `understudy.cardinality` | [`SpecificationCheck`](https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/SpecificationCheck.php) | Says what the engine would say, before the test runs. | -| `understudy.closure` | [`SpecificationCheck`](https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/SpecificationCheck.php) | Says what the engine would say, before the test runs. | -| `understudy.matcher` | [`SpecificationCheck`](https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Internal/SpecificationCheck.php) | Says what the engine would say, before the test runs. | -| `understudy.matcherLeak` | [`MatcherLeakRule`](https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Rule/MatcherLeakRule.php) | A matcher written outside a specification. | -| `understudy.returns` | [`VoidReturnsRule`](https://github.com/rasuvaeff/understudy-phpstan/blob/04cc11b417ff29a6877b0dd6cae345d4d7a4ba16/src/PhpStan/Rule/VoidReturnsRule.php) | `returns()` on a method that returns nothing. | +| `understudy.cardinality` | [`SpecificationCheck`](https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/SpecificationCheck.php) | Says what the engine would say, before the test runs. | +| `understudy.closure` | [`SpecificationCheck`](https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/SpecificationCheck.php) | Says what the engine would say, before the test runs. | +| `understudy.matcher` | [`SpecificationCheck`](https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Internal/SpecificationCheck.php) | Says what the engine would say, before the test runs. | +| `understudy.matcherLeak` | [`MatcherLeakRule`](https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Rule/MatcherLeakRule.php) | A matcher written outside a specification. | +| `understudy.returns` | [`VoidReturnsRule`](https://github.com/rasuvaeff/understudy-phpstan/blob/6d3fb1ca06d092dc613881efd6fe66bafa970914/src/PhpStan/Rule/VoidReturnsRule.php) | `returns()` on a method that returns nothing. | Silence one by its identifier: @@ -35,11 +35,11 @@ parameters: - `Rasuvaeff\Understudy\PhpStan\Rule\VoidReturnsRule` - `Rasuvaeff\Understudy\PhpStan\Rule\MatcherLeakRule` -## Psalm · `rasuvaeff/understudy-psalm` v0.8.3 +## Psalm · `rasuvaeff/understudy-psalm` v1.0.0 | Issue type | Summary | |---|---| -| [`UnderstudyMisuse`](https://github.com/rasuvaeff/understudy-psalm/blob/adfcb7751dd3bc241d0cee864a6e3c47d19aca1a/src/Psalm/Issue/UnderstudyMisuse.php) | A specification that cannot mean what it says. | +| [`UnderstudyMisuse`](https://github.com/rasuvaeff/understudy-psalm/blob/94a16bb9675d36734e26a394f6aa54a142a2ccfc/src/Psalm/Issue/UnderstudyMisuse.php) | A specification that cannot mean what it says. | The plugin reports its own findings under that one issue type; everything else it surfaces is Psalm's own diagnostic, made possible by the types the plugin fills in. diff --git a/perf/README.md b/perf/README.md index 8ed5283..2fadd0b 100644 --- a/perf/README.md +++ b/perf/README.md @@ -93,9 +93,9 @@ figure, is the only thing worth quoting. Environment: PHP 8.5.6, Linux x86_64, `composer:2` image, no OPcache, no Xdebug. The container is pinned to six cores with a raised CPU share — by the `PERF` -variable in the root `Makefile`, not by flags typed at a prompt. Understudy at -`442da10`, Mockery 1.6.15, Prophecy 1.26.1, PHPUnit 12.5.33. Taken 2026-08-27, -before the 0.2.0 tag. +variable in the root `Makefile`, not by flags typed at a prompt. Understudy +`v1.0.0` (`d044131`), Mockery 1.6.15, Prophecy 1.26.1, PHPUnit 12.5.36. +Taken 2026-09-27. **Re-verified for the v0.5.0 tag on 2026-09-03**, and left unchanged because there was nothing to change. Three runs of the full harness at `442da10` — the @@ -139,6 +139,16 @@ change. The absolutes on that machine read about 2.3x the figures below, which is exactly the reason the ratio is what gets quoted and why the numbers here were not replaced with the ones it produced. +**Re-measured for `v1.0.0` on 2026-09-27.** Three full runs at `442da10` and +three at `v1.0.0`, in one sitting with the same CPU pinning. The candidate's +filtered medians moved by about +20% on double creation and verified mocks, ++18% on a 20-call stub, and +24% on a one-call stub. Memory per live double is +571–586 B versus 467–482 B at the baseline. The competitor movement stayed in +the noise floor, so these are attributable changes and the tables below now +describe the 1.0.0 candidate. Cold start is nearly tied with Mockery (3.24 ms +versus 3.10 ms added to the process); the ratio is reported rather than the +absolute because process startup is noisy. + Every in-process table below was run three times; medians move by 0.2-3.5% between runs. Figures are **filtered means** — testo's `Mean*`, after outlier rejection — and the relative deviation of that filtered set is under 5% @@ -158,10 +168,10 @@ worth acting on. | Contract | understudy | Mockery | Prophecy | PHPUnit `createStub` | PHPUnit `createMock` | |---|---|---|---|---|---| -| 1 method | **2.06µs** | +216% | +683% | +155% | +159% | -| 8 methods | **2.06µs** | +217% | +641% | +158% | +159% | +| 1 method | **2.69µs** | +148% | +497% | +102% | +115% | +| 8 methods | **2.67µs** | +149% | +478% | +104% | +113% | -The cost still does not move with the width of the contract — 2.06µs either way +The cost still does not move with the width of the contract — 2.69µs either way — because the generated class is compiled once and everything after that is instantiation. A busy machine will suggest otherwise; it is wrong. @@ -172,9 +182,9 @@ regression described above, not a change since 0.1.2. | | understudy | Mockery | Prophecy | PHPUnit `createStub` | |---|---|---|---|---| -| 1 call | 10.6µs | +17% | +76% | **−17%** | -| 20 calls | 27.1µs | +59% | +75% | **−19%** | -| marginal cost of one call² | 0.86µs | 1.61µs | 1.51µs | **0.69µs** | +| 1 call | 12.8µs | −8% | +33% | **−34%** | +| 20 calls | 32.1µs | +33% | +49% | **−32%** | +| marginal cost of one call² | 1.02µs | 1.62µs | 1.50µs | **0.70µs** | ¹ Prophecy's twenty-call row was unquotable in the previous set — ±72% after filtering. On an idle machine it settles to ±3.7% and is quoted here. @@ -183,8 +193,8 @@ filtering. On an idle machine it settles to ±3.7% and is quoted here. **PHPUnit is ahead of understudy on the whole stub scenario, at both ends.** It builds the double more slowly and dispatches more cheaply, and in this -environment the second effect wins from the first call onward: 8.77µs against -10.6µs at one call, 0.69µs against 0.86µs per call after. There is no crossover +environment the second effect wins from the first call onward: 8.47µs against +12.81µs at one call, 0.70µs against 1.02µs per call after. There is no crossover at which understudy's stub test becomes the cheaper one. That is a change of conclusion, not only of numbers. The previous figures had @@ -198,13 +208,13 @@ PHPUnit from 1.62× to 1.15× — and it moved the build cost too, from 2.08µs | | understudy | Mockery | Prophecy | PHPUnit `createMock` | |---|---|---|---|---| -| plain expectation | 12.8µs | +4% | +128% | **−27%** | -| with an argument matcher | **12.2µs** | +5% | +115% | —³ | +| plain expectation | 16.0µs | −16% | +89% | **−41%** | +| with an argument matcher | **15.5µs** | −15% | +76% | —³ | ³ see "What is deliberately absent" above. An argument matcher costs understudy nothing measurable over a plain -expectation — 10.77µs either way. +expectation — 16.04µs versus 15.48µs in these runs. ### Cold start @@ -214,24 +224,23 @@ more between runs than testo calls stable, and the ratios hold much better. | library | added to process start | ×understudy | |---|---|---| -| understudy | 1.59ms | **1.00×** | -| Mockery | 2.39ms | 1.50× | -| Prophecy | 7.91ms | 4.96× | -| PHPUnit | 8.58ms | 5.38× | +| understudy | 3.24ms | **1.00×** | +| Mockery | 3.10ms | 0.96× | +| Prophecy | 8.70ms | 2.69× | +| PHPUnit | 9.42ms | 2.91× | -Mockery's ratio has been unstable across sets — 1.87×, then 1.30–1.53×, now -1.50× — across commits that cannot touch Mockery. Recorded as observed, without -a cause. +Mockery's ratio has been unstable across sets — it is marginally faster than +understudy in this release run. That is recorded as observed, without a cause. ### Memory 500 live doubles per contract, after one warmup double per library so that the library''s own autoloading is not billed to the first contract measured. -Deterministic: two runs, identical to the byte. +Deterministic: three runs per side, identical to the byte. | library | first double of a contract | each further double | |---|---|---| -| understudy | 4.5 KB (`Clock`), 13.6 KB (`Ledger`) | **467–482 B** | +| understudy | 4.7 KB (`Clock`), 17.4 KB (`Ledger`) | **571–586 B** | | Mockery | 126.3 KB, 140.8 KB | 513 B | | Prophecy | 13.5 KB, 35.5 KB | ~8.5 KB | | PHPUnit | 9.5 KB, 134.6 KB | ~1.25 KB | @@ -247,6 +256,7 @@ the movement is code: | after #9–#14 (class doubles, forwarding, defaults, by-ref, bypass) | 418 B | 403 B | | after #16 (dispatch) | 450 B | 435 B | | at `442da10`, before 0.2.0 | 482 B | 467 B | +| `v1.0.0` | 586 B | 571 B | The last row is another 32 bytes, over the same range that carries the #23 creation regression. It has not been attributed to a single change.