*/ public static function templateReferenceProvider(): iterable { $templatesDir = \dirname(__DIR__, 2).'/templates'; $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($templatesDir, \RecursiveDirectoryIterator::SKIP_DOTS), ); foreach ($iterator as $file) { Assert::assertInstanceOf(\SplFileInfo::class, $file); if ('twig' !== $file->getExtension()) { continue; } $content = file_get_contents($file->getPathname()); $sourceFile = str_replace($templatesDir.'/', '', $file->getPathname()); // Match extends, include(), and embed tags — capture the quoted template name preg_match_all( '/(?:extends|include|embed)\s*\(?[\'"]([^\'"]+)[\'"]\)?/', $content, $matches, ); foreach ($matches[1] as $referencedTemplate) { yield \sprintf('%s → %s', $sourceFile, $referencedTemplate) => [$sourceFile, $referencedTemplate]; } } } #[DataProvider('templateReferenceProvider')] public function testReferencedTemplateExists(string $sourceFile, string $referencedTemplate): void { $absolutePath = self::$templatesDir.'/'.$referencedTemplate; $this->assertFileExists( $absolutePath, \sprintf("Template '%s' references '%s' which does not exist at '%s'.", $sourceFile, $referencedTemplate, $absolutePath), ); } }