Repository navigation
feat(phpt): add PHP .phpt filter for php-src run-tests.php (-99%) - #1503
Conversation
📊 Automated PR Analysis
SummaryAdds a new Review Checklist
Analyzed automatically by wshm · This is an automated analysis, not a human review. |
…pest, paratest, ecs, pint) Consolidates the PHP-tooling work from three upstream PRs plus a new Pint module, leaving phpt to its own PR (rtk-ai#1503). - rtk php / rtk artisan: syntax check (-l) and Laravel artisan wrapper. - rtk phpunit: structured-state parser, aggregate counts, bounded failure list. Uses runner::run_filtered. - rtk phpstan: typed serde::Deserialize parser for --error-format=json, groups errors by file, sorts by count desc. Utility commands (--version, list, clear-result-cache) pass through unchanged. - rtk pest / rtk paratest: shared test_output helper. - rtk ecs / rtk pint: code-style fixers; pint uses --format=json for structured per-file rule counts. Composer custom-bin-dir detection: composer_bin_dirs() reads COMPOSER_BIN_DIR and composer.json config.bin-dir, so tools/bin/phpunit classifies identically to vendor/bin/phpunit. registry.rs normalizes tool paths before matching. Sources: - rtk-ai#1246 (aaronflorey, self-closed): php, artisan, ecs, pest, paratest, test_output, utils, composer_bin_dirs, registry normalization. - rtk-ai#874 (Beninho, open): phpunit state-machine parser. - rtk-ai#1110 (LucianoVandi, open): phpstan typed parser. - New: pint_cmd.rs. Tests: discover::registry 253 pass; cmds::php 36 pass; cargo build --release 0 errors; cargo fmt --check clean.
…pest, paratest, ecs, pint) Consolidates the PHP-tooling work from three upstream PRs plus a new Pint module, leaving phpt to its own PR (rtk-ai#1503). - rtk php / rtk artisan: syntax check (-l) and Laravel artisan wrapper. - rtk phpunit: structured-state parser, aggregate counts, bounded failure list. Uses runner::run_filtered. - rtk phpstan: typed serde::Deserialize parser for --error-format=json, groups errors by file, sorts by count desc. Utility commands (--version, list, clear-result-cache) pass through unchanged. - rtk pest / rtk paratest: shared test_output helper. - rtk ecs / rtk pint: code-style fixers; pint uses --format=json for structured per-file rule counts. Composer custom-bin-dir detection: composer_bin_dirs() reads COMPOSER_BIN_DIR and composer.json config.bin-dir, so tools/bin/phpunit classifies identically to vendor/bin/phpunit. registry.rs normalizes tool paths before matching. Sources: - rtk-ai#1246 (aaronflorey, self-closed): php, artisan, ecs, pest, paratest, test_output, utils, composer_bin_dirs, registry normalization. - rtk-ai#874 (Beninho, open): phpunit state-machine parser. - rtk-ai#1110 (LucianoVandi, open): phpstan typed parser. - New: pint_cmd.rs. Tests: discover::registry 253 pass; cmds::php 36 pass; cargo build --release 0 errors; cargo fmt --check clean.
…pest, paratest, ecs, pint) Consolidates the PHP-tooling work from three upstream PRs plus a new Pint module, leaving phpt to its own PR (rtk-ai#1503). - rtk php / rtk artisan: syntax check (-l) and Laravel artisan wrapper. - rtk phpunit: structured-state parser, aggregate counts, bounded failure list. Uses runner::run_filtered. - rtk phpstan: typed serde::Deserialize parser for --error-format=json, groups errors by file, sorts by count desc. Utility commands (--version, list, clear-result-cache) pass through unchanged. - rtk pest / rtk paratest: shared test_output helper. - rtk ecs / rtk pint: code-style fixers; pint uses --format=json for structured per-file rule counts. Composer custom-bin-dir detection: composer_bin_dirs() reads COMPOSER_BIN_DIR and composer.json config.bin-dir, so tools/bin/phpunit classifies identically to vendor/bin/phpunit. registry.rs normalizes tool paths before matching. Sources: - rtk-ai#1246 (aaronflorey, self-closed): php, artisan, ecs, pest, paratest, test_output, utils, composer_bin_dirs, registry normalization. - rtk-ai#874 (Beninho, open): phpunit state-machine parser. - rtk-ai#1110 (LucianoVandi, open): phpstan typed parser. - New: pint_cmd.rs. Tests: discover::registry 253 pass; cmds::php 36 pass; cargo build --release 0 errors; cargo fmt --check clean.
…pest, paratest, ecs, pint) Consolidates the PHP-tooling work from three upstream PRs plus a new Pint module, leaving phpt to its own PR (rtk-ai#1503). - rtk php / rtk artisan: syntax check (-l) and Laravel artisan wrapper. - rtk phpunit: structured-state parser, aggregate counts, bounded failure list. Uses runner::run_filtered. - rtk phpstan: typed serde::Deserialize parser for --error-format=json, groups errors by file, sorts by count desc. Utility commands (--version, list, clear-result-cache) pass through unchanged. - rtk pest / rtk paratest: shared test_output helper. - rtk ecs / rtk pint: code-style fixers; pint uses --format=json for structured per-file rule counts. Composer custom-bin-dir detection: composer_bin_dirs() reads COMPOSER_BIN_DIR and composer.json config.bin-dir, so tools/bin/phpunit classifies identically to vendor/bin/phpunit. registry.rs normalizes tool paths before matching. Sources: - rtk-ai#1246 (aaronflorey, self-closed): php, artisan, ecs, pest, paratest, test_output, utils, composer_bin_dirs, registry normalization. - rtk-ai#874 (Beninho, open): phpunit state-machine parser. - rtk-ai#1110 (LucianoVandi, open): phpstan typed parser. - New: pint_cmd.rs. Tests: discover::registry 253 pass; cmds::php 36 pass; cargo build --release 0 errors; cargo fmt --check clean.
|
Rebased onto |
|
Heads-up on the red |
Yes I'll check the benchmark, I've fixed a reliability problem but introduced a flakiness :/ Sorry about that |
|
Hi @iliaal, sorry for the delay I was away for 2 weeks. I've reverted the insta part of your code as it was a mistake, our documentation was outdated and I blindly followed it, my bad, sorry. Everything looks good to me, but in the meanwhile, Thanks |
Wraps `php run-tests.php` and collapses its per-test PASS chatter into one summary line plus a bounded list of failure diffs. On php-src's 5322-test suite with 467 failures, output drops from 1.3 MB to 6 KB (99.5% reduction). An all-pass run collapses to two lines. Handles PASS/FAIL/SKIP/BORK/WARN/LEAK/XFAIL/XLEAK, ANSI color codes, the ========DIFF======== / ========DONE======== blocks, and the trailing FAILED TEST SUMMARY block (which must not be re-counted). XFAIL and XLEAK are expected results (reported under "Expected fail"/"Expected leak" by run-tests.php) and do not count as failures. The hook rewrite maps `php run-tests.php …` to `rtk phpt …` via a rule in discover/rules.rs, with `phpt` added to the passthrough classifier. Diff buffering is capped at the display limit while a separate counter keeps the "+N more diff lines" note accurate. When the summary block reports failures but per-test lines were truncated out of the capture, the FAILURES header is still emitted with a note rather than dropped. Tests: inline units plus an insta snapshot and a count_tokens-based token-savings assertion (>=60%), per .claude/rules/cli-testing.md.
It was my fault I shouldn't have made that request
Running the filter against php-src instead of captured fixtures exposed
three defects.
run-tests.php redraws its progress line, so a serial run (no -j) delivers
the status after a carriage return: "TEST 1/2 [x.phpt]\rFAIL desc
[x.phpt]". The status anchor never matched, so every per-test status was
lost and failures printed as "details unavailable". Splitting on CR fixes
it. The original 5322-test validation ran with -j8, where workers suppress
the progress line, which is why this stayed hidden.
php writes its startup diagnostics to stderr ("Could not open input file:
run-tests.php", the illegal-switch help), and stdout_only dropped them.
The never-worse guard then had an empty base, so rtk printed nothing at
all. The filter now reads both streams and passes output through unchanged
when it isn't run-tests.php output.
run-tests.php emits DIFF blocks only with --show-diff or for a single
selected test, so multi-test runs listed failing test names without a
diff. rtk now asks for them unless the caller passed its own --show-* flag.
Verified on php-src: 733-test serial run, 12 failures with diffs, 97.1%
reduction (153884 to 4476 bytes).
|
Rebased onto On the guard: Verifying that against real php-src turned up two more, both mine from the original commit: Serial runs lost every per-test status. run-tests.php redraws its progress line, so without No diffs on multi-test runs. run-tests.php emits Verified on php-src, serial run of 153,884 → 4,476 bytes, 97.1%. The wrong-directory case now prints
|
…pest, paratest, ecs, pint) Consolidates the PHP-tooling work from three upstream PRs plus a new Pint module, leaving phpt to its own PR (rtk-ai#1503). - rtk php / rtk artisan: syntax check (-l) and Laravel artisan wrapper. - rtk phpunit: structured-state parser, aggregate counts, bounded failure list. Uses runner::run_filtered. - rtk phpstan: typed serde::Deserialize parser for --error-format=json, groups errors by file, sorts by count desc. Utility commands (--version, list, clear-result-cache) pass through unchanged. - rtk pest / rtk paratest: shared test_output helper. - rtk ecs / rtk pint: code-style fixers; pint uses --format=json for structured per-file rule counts. Composer custom-bin-dir detection: composer_bin_dirs() reads COMPOSER_BIN_DIR and composer.json config.bin-dir, so tools/bin/phpunit classifies identically to vendor/bin/phpunit. registry.rs normalizes tool paths before matching. Sources: - rtk-ai#1246 (aaronflorey, self-closed): php, artisan, ecs, pest, paratest, test_output, utils, composer_bin_dirs, registry normalization. - rtk-ai#874 (Beninho, open): phpunit state-machine parser. - rtk-ai#1110 (LucianoVandi, open): phpstan typed parser. - New: pint_cmd.rs. Tests: discover::registry 253 pass; cmds::php 36 pass; cargo build --release 0 errors; cargo fmt --check clean.
--show-diff was injected unless any --show-* flag was present, but only --show-diff and --show-all produce the DIFF block. --show-slow, --show-mem, --show-out, etc. don't, so `rtk phpt --show-slow 1000 …` suppressed the injected --show-diff and stripped every failure of its actionable diff. Match only --show-diff/--show-all, print the truthful injected command in verbose mode, and add a regression test for the --show-slow case.
Port of 127de99 (phpt-support / PR rtk-ai#1503 r2). --show-diff was injected unless any --show-* flag was present, but only --show-diff and --show-all produce the DIFF block; --show-slow/--show-mem/--show-out don't, so those flags suppressed the injection and stripped every failure of its diff. Match only --show-diff/--show-all, print the truthful injected command in verbose mode, and add a regression test for the --show-slow case.
Port of 127de99 (phpt-support / PR rtk-ai#1503 r2). --show-diff was injected unless any --show-* flag was present, but only --show-diff and --show-all produce the DIFF block; --show-slow/--show-mem/--show-out don't, so those flags suppressed the injection and stripped every failure of its diff. Match only --show-diff/--show-all, print the truthful injected command in verbose mode, and add a regression test for the --show-slow case.
Port of 127de99 (phpt-support / PR rtk-ai#1503 r2). --show-diff was injected unless any --show-* flag was present, but only --show-diff and --show-all produce the DIFF block; --show-slow/--show-mem/--show-out don't, so those flags suppressed the injection and stripped every failure of its diff. Match only --show-diff/--show-all, print the truthful injected command in verbose mode, and add a regression test for the --show-slow case.
Port of 127de99 (phpt-support / PR rtk-ai#1503 r2). --show-diff was injected unless any --show-* flag was present, but only --show-diff and --show-all produce the DIFF block; --show-slow/--show-mem/--show-out don't, so those flags suppressed the injection and stripped every failure of its diff. Match only --show-diff/--show-all, print the truthful injected command in verbose mode, and add a regression test for the --show-slow case.
Port of 127de99 (phpt-support / PR rtk-ai#1503 r2). --show-diff was injected unless any --show-* flag was present, but only --show-diff and --show-all produce the DIFF block; --show-slow/--show-mem/--show-out don't, so those flags suppressed the injection and stripped every failure of its diff. Match only --show-diff/--show-all, print the truthful injected command in verbose mode, and add a regression test for the --show-slow case.
Summary
Adds
rtk phpt, a filter forphp run-tests.php. It's the driver php-src and PHP extensions use for their.phpttest suite.A full php-src run emits one status line per test plus a
========DIFF========block per failure. On a 5322-test run that's about 1.3 MB of output, 99%+ of which is PASS chatter. After filtering:Filtered output keeps what the agent needs: aggregate counts, PHP version/SAPI/OS, and up to 20 failures with the first 6 diff lines each.
Example
Usage
Implementation
src/cmds/php/phpt_cmd.rsis a new filter module modeled onpython/pytest_cmd.rs: stateful line scan, regex anchors, inline tests.Status tokens match via
(?:^|\])(PASS|FAIL|SKIP|BORK|WARN|LEAK|XFAIL)\s+(.*?)\s*\[([^\[\]]+\.phpt)\]. The(?:^|\])anchor is what prevents the trailingFAILED TEST SUMMARYblock from being re-counted. Its lines aredescription [path]with no status tag.ANSI is stripped via the existing
utils::strip_ansi. Execution goes throughrunner::run_filteredwithstdout_only().tee("phpt"), same as pytest. The command is added to theis_operational_commandwhitelist so it flows through the hook pipeline.Tests
12 inline unit tests:
FAILED TEST SUMMARYblock doesn't re-count failuresPHP_OSkernel info trimmed to just the OS familyTest plan
cargo test -p rtk phptpasses 12/12cargo fmt --all -- --checkcleancargo clippy -p rtkno new warnings in diff (pre-existing errors unchanged)rtk phpt Zend/tests/67468.phpton real php-src, correct outputrtk phpt Zend/tests/ArrayAccess/(11 tests), correct output