Conversation
ci: point the coverage upload at Testo's clover report chore(psalm): forbid dump() and error_log() Suites in testo.php mirror the phpunit.xml.dist testsuites. No plugins are declared: Testo's defaults already ship an inert JUnit and Codecov plugin that the `--log-junit=` / `--coverage-*` flags activate, so report paths stay in the composer scripts instead of the config. The Arch suite goes away with phpunit-architecture-test. Its only check was a list of forgotten debug functions, which psalm's forbiddenFunctions already covered except for dump() and error_log() — hence the two additions there. The tests themselves are still PHPUnit-based, so nothing is discovered yet; phpunit.xml.dist stays until they are ported. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Checkpoint commit: `testo/bridge-rector`'s phpunit-to-testo set converted the assertions (with the expected/actual swap), lifecycle methods, data providers, coverage attributes and the TestCase base class. The structural residue — mocks, non-mapped assertions, method renames — is finished in the next commits. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Drops the leftover `use PHPUnit\…;` imports, turns the fully-qualified `\Testo\…` names the bridge emits into real imports, renames `testFoo()` → `foo()` and the PHPUnit lifecycle methods, and strips the Arrange/Act/Assert labels — Testo separates phases with a blank line. Test counts and results are unchanged by this commit; the remaining failures are mocks and unmapped assertions. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
test(velox): key the GitHub client stub on the request instance Testo ships no mocking, so `MockeryPlugin` is registered in `testo.php` and the `createMock()` doubles became `\Mockery::mock()`. Placeholder doubles that were never configured get `shouldIgnoreMissing()` — that is what PHPUnit's `createMock()` did, and `ClientStub` relied on it: it derived its lookup key from `getMethod()`/`getUri()`, which collapsed every unconfigured request into one bucket. The key is now the request instance itself. The PSR-18 client exception stays a real exception class: Mockery cannot mock a `Throwable` descendant. Also closes the two conversions the Rector bridge does not do — the assertions missing from its map (`assertStringContainsString` and friends) and the exception messages, where the bridge emits the exact-match `withMessage()` for PHPUnit's substring `expectExceptionMessage()`. Both are reported upstream in php-testo/testo#270. Whole suite green under Testo: 453 passed, 3 skipped. `phpunit.xml.dist` and the disposable Rector config are gone. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ci: drop PHP 8.1 from the testing matrix `--color=always` was carried over from the PHPUnit scripts; Testo has no such option and every `composer test` run failed on it. PHP 8.1 was already below the `>=8.2` requirement in composer.json, so those matrix jobs could not install. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The source message ends with a period while the expectation does not, and the Testo withMessage() is an exact match where the PHPUnit expectExceptionMessage() was a substring one. Not caught locally: the test skips itself on Windows, where chmod cannot make a file unreadable. Assisted-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 🚀 New features to boost your workflow:
|
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔍 What was changed
phpunit.xml.dist→testo.phpwith one suite per former testsuite, PHPUnit gone fromcomposer.json. 456 tests — 453 passed, 3 skipped, none deleted or weakened.testo/bridge-mockery(Testo core ships none).MockeryPluginverifies expectations and clears the container after every test, so no teardown boilerplate and mock-only tests stay out ofStatus::Risky.tests/Archis dropped. Its only check was a forgotten-debug-function list that Psalm'sforbiddenFunctionsalready covered, exceptdumpanderror_log— both added topsalm.xml, neither used insrc.phpunit.jsonproblem matcher is removed (Testo ships none), Codecov readsruntime/coverage/clover.xml, and PHP 8.1 leaves the matrix — it was already below the>=8.2requirement.Why?
Two things are worth a reviewer's attention, both places where the automated conversion was wrong rather than merely incomplete:
expectExceptionMessage()matches a substring, Testo'swithMessage()matches exactly. The Rector bridge emits the latter, which silently broke 15 cases — e.g. expecting'Version constraint cannot be empty'against a SUT throwing the same string with a trailing period. 8 sites are nowwithMessageContaining(); the rest were exact already and keep the stronger assertion.ClientStubkeys on the request instance. It used to build its key fromgetMethod()andgetUri(), which only worked because PHPUnit'screateMock()returns a cached auto-double per method, collapsing every unconfigured request into the single key'|'. Mockery returns a fresh double per call. The key is nowspl_object_id($request), independent of any mock's defaults. This is also why two tests inClientTestalways compared withassertEqualsrather thanassertSame.The bridge gaps found on the way are reported upstream in php-testo/testo#270: the
withMessagemistranslation, the assertions missing from its map (assertStringContainsStringalone was 43 call sites here), and that the mock conversion is in fact mechanical against Mockery.Checklist
453 passed, 3 skippedof 456testingmatrix green in CI across PHP 8.2–8.5 × lowest/locked/highestpsalmis red, and was already red on1.xbefore this branch — every error is insrc/files this PR does not touch, and none is aForbiddenCodefrom thepsalm.xmlchangecode-coverageis red because the Acceptance suite downloads from the GitHub API anonymously and hitrate limit exceeded (limit: 60 requests per hour)after the 12testingjobs; unrelated to the migration, but the suite needs aGITHUB_TOKENin CI to be reliableReview notes
Four commits, each verifiable on its own:
b8fed24runner config ·5b86ef7the mechanical Rector pass ·f8359e0what Rector left behind, with test counts and results unchanged ·273bfcbmocks, the unmapped assertions and the message fixes.#[Test]sits on the methods rather than the class. Testo prefers a single class-level marker when every public method is a test, which holds for essentially all of these classes — happy to hoist it here or leave it as a follow-up.