From de6fcac5358bd940fdc0e1a7406a5edda626cab7 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 19 Jul 2026 15:41:36 +0700 Subject: [PATCH] test: ensure cached class nodes never carry stale isExtended flag --- tests/Analyser/AnalyserTest.php | 56 +++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/Analyser/AnalyserTest.php b/tests/Analyser/AnalyserTest.php index 81a2d33..0a141de 100644 --- a/tests/Analyser/AnalyserTest.php +++ b/tests/Analyser/AnalyserTest.php @@ -141,6 +141,62 @@ public function testMustBeFinalRuleFlagsExtendedClassWhenChildIsOutsideScannedPa $this->assertSame('App\BaseHandler', $violations[0]->className); } + public function testMustBeFinalRuleReportsSameExtendedClassesOnCachedRun(): void + { + $basePath = $this->makeTempProject([ + 'src/BaseHandler.php' => ' ' 'layer('Source', 'src/') + ->rule('source.must_be_final', new MustBeFinalRule('Source')); + + $coldViolations = (new Analyser($basePath, $analysisResultCache, 'config')) + ->analyse($architecture, [], null, AnalyserOptions::sequential()) + ->forRule('source.must_be_final'); + $warmViolations = (new Analyser($basePath, $analysisResultCache, 'config')) + ->analyse($architecture, [], null, AnalyserOptions::sequential()) + ->forRule('source.must_be_final'); + + $this->assertCount(1, $coldViolations); + $this->assertSame('App\PaymentHandler', $coldViolations[0]->className); + $this->assertCount(1, $warmViolations); + $this->assertSame('App\PaymentHandler', $warmViolations[0]->className); + } + + public function testMustBeFinalRuleFlagsCachedClassOnceItsExtendingClassIsRemoved(): void + { + $basePath = $this->makeTempProject([ + 'src/BaseHandler.php' => ' 'layer('Source', 'src/') + ->rule('source.must_be_final', new MustBeFinalRule('Source')); + + $coldViolations = (new Analyser($basePath, $analysisResultCache, 'config')) + ->analyse($architecture, [], null, AnalyserOptions::sequential()) + ->forRule('source.must_be_final'); + + $this->assertCount(0, $coldViolations); + + // BaseHandler.php is untouched, so its class-node cache entry stays valid; + // the extended flag must still be recomputed against the shrunken class set. + unlink($basePath . '/src/OrderHandler.php'); + + $warmViolations = (new Analyser($basePath, $analysisResultCache, 'config')) + ->analyse($architecture, [], null, AnalyserOptions::sequential()) + ->forRule('source.must_be_final'); + + $this->assertCount(1, $warmViolations); + $this->assertSame('App\BaseHandler', $warmViolations[0]->className); + } + public function testAnalyserMarksFixableRuleViolations(): void { $basePath = $this->makeTempProject([