rectorphp/rector · error · ShouldNotHappenException

Fixture file and input file cannot be the same:

Error message

Fixture file and input file cannot be the same: 

What it means

AbstractRectorTestCase::doTestFile() splits a fixture into input/expected halves and writes the input half to a derived temp path (createInputFilePath()). Before FileSystem::write(), it verifies the derived path differs from the fixture path; equality would mean the write destroys the source fixture, so it throws ShouldNotHappenException with the colliding path.

Source

Thrown at src/Testing/PHPUnit/AbstractRectorTestCase.php:146

        return null;
    }
    protected function doTestFile(string $fixtureFilePath, bool $includeFixtureDirectoryAsSource = \false): void
    {
        // prepare input file contents and expected file output contents
        $fixtureFileContents = FileSystem::read($fixtureFilePath);
        if (FixtureSplitter::containsSplit($fixtureFileContents)) {
            // changed content
            [$inputFileContents, $expectedFileContents] = FixtureSplitter::splitFixtureFileContents($fixtureFileContents);
        } else {
            // no change
            $inputFileContents = $fixtureFileContents;
            $expectedFileContents = $fixtureFileContents;
        }
        $inputFilePath = $this->createInputFilePath($fixtureFilePath);
        // to remove later in tearDown()
        $this->inputFilePath = $inputFilePath;
        if ($fixtureFilePath === $inputFilePath) {
            throw new ShouldNotHappenException('Fixture file and input file cannot be the same: ' . $fixtureFilePath);
        }
        // write temp file
        FileSystem::write($inputFilePath, $inputFileContents, null);
        $this->doTestFileMatchesExpectedContent($inputFilePath, $inputFileContents, $expectedFileContents, $fixtureFilePath, $includeFixtureDirectoryAsSource);
    }
    protected function doTestFileExpectingWarningAboutRuleApplied(string $fixtureFilePath, string $expectedRuleApplied): void
    {
        ob_start();
        $this->doTestFile($fixtureFilePath);
        $content = ob_get_clean();
        $fixtureName = basename($fixtureFilePath);
        $testClass = static::class;
        $this->assertSame(\PHP_EOL . 'WARNING: On fixture file "' . $fixtureName . '" for test "' . $testClass . '"' . \PHP_EOL . 'File not changed but some Rector rules applied:' . \PHP_EOL . ' * ' . $expectedRuleApplied . \PHP_EOL, $content);
    }
    private function forgetRectorsRules(): void
    {
        $rectorConfig = self::getContainer();
        // 1. forget tagged services

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Keep fixtures outside the temp/input directory (standard tests/Fixtures/ layout) so paths can never collide
  2. If you override createInputFilePath(), ensure it appends a distinct suffix (e.g. '.input' or '/input/') that the fixture itself does not carry
  3. Clear stale temp files between runs and re-run the test

Example fix

// before: fixture and derived input path coincide
protected function createInputFilePath(string $fixtureFilePath): string
{
    return $fixtureFilePath; // identical -> throws
}

// after
protected function createInputFilePath(string $fixtureFilePath): string
{
    return $fixtureFilePath . '.input';
}
Defensive patterns

Strategy: validation

Validate before calling

// guard before doTestFile()
$inputFilePath = $this->createInputFilePath($fixtureFilePath);
if ($inputFilePath === $fixtureFilePath) {
    self::markTestSkipped(sprintf('Fixture %s collides with its derived input path; move it out of the temp dir.', $fixtureFilePath));
}

Prevention

When it happens

Trigger: The fixture already sits where the derived input path points — typically fixtures stored inside the temp directory that createInputFilePath() also uses, or a fixture filename whose transform (suffixing/extension swap) maps onto itself.

Common situations: Test suites relocated into sys_get_temp_dir() for CI isolation; a custom test case overriding createInputFilePath() without changing the suffix; running tests twice with cached temp fixtures from a prior aborted run.

Related errors


AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21). Data as JSON: /api/errors/93e8f445a903eb98. Report an issue: GitHub.