Skip to content

fix(tia): link files a test reads as text, not only files it executes - #2006

Open
jbraband wants to merge 1 commit into
pestphp:5.xfrom
jbraband:fix/tia-read-capture
Open

jbraband wants to merge 1 commit into
pestphp:5.xfrom
jbraband:fix/tia-read-capture

Conversation

@jbraband

Copy link
Copy Markdown

What:

  • Bug Fix
  • New Feature

Description:

Under --tia, a test that reads a project file as text (instead of executing or rendering it) replays a stale pass after that file changes. Coverage and BladeEdges give it no edge to the file, and the watch patterns skip any file the graph already knows (Graph::applyWatchPatternFallback()), so nothing selects it.

This PR records the files a test reads:

  • src/Plugins/Tia/ReadCapture.php (new): a file:// stream wrapper, registered only while a test records (Recorder::beginTest() to endTest()). It forwards every operation, and links each file opened for reading through Recorder::linkSource(), the hook BladeEdges uses. It skips includes, which coverage already records, and write-only opens. If another wrapper already owns file:// (such as dg/bypass-finals or Patchwork), it opens through that wrapper with the original flags and registers it again after the test.
  • src/Plugins/Tia/Recorder.php: starts and stops the capture, and adds linkRead(), which keeps project files only through SourceScope.

On a fresh Laravel 13 skeleton, the patch adds exactly one graph edge (the reading test to the view), and recording takes about 4% longer. Plain runs are unchanged. Capture is on by default; I am happy to put it behind an opt-in such as pest()->tia()->captureReads() instead.

Tests:

  • tests/Unit/Plugins/Tia/ReadCapture.php: what is linked (reads through file_get_contents, file, fopen, SplFileObject) and what is not (writes, includes, files outside the project, directory listings), that the wrapper is swapped and restored, that filesystem operations pass through, and that an existing file:// wrapper is chained with its include flag.
  • tests/Features/Tia/ReadCapture.php: in the fixture app, a test that reads app/Greeter.php records an edge to it and is selected when it changes (sequential and parallel), and is not selected when an unrelated file changes.

Known gaps: directory listings (scandir, glob) are not captured, and while a test records, a failed open raises two warnings instead of one, as mutate's wrapper does.

Related:

Fixes #2005

Reproduction: https://github.com/jbraband/pest-tia-reads-reproduction

@jbraband
jbraband force-pushed the fix/tia-read-capture branch from 8143b6a to 8d3f111 Compare November 4, 2026 19:46
@jbraband

jbraband commented Nov 4, 2026

Copy link
Copy Markdown
Author

Rebased onto 5.x at e107ac7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: TIA replays a stale pass for a test that reads a file as text, even under the built-in watch patterns

1 participant