setFileExtension(Format::HTML); $configuration->setUseCachedMetas(false); $kernel = new Kernel($configuration); $builder = new Builder($kernel); $builder->build(__DIR__ . '/tests/build/' . $file, __DIR__ . '/output/build/' . $file); $outputFileFinder = new Finder(); $outputFileFinder ->files() ->in(__DIR__ . '/output/build/' . $file) ->name('index.html'); foreach ($outputFileFinder as $outputFile) { $rendered = $outputFile->getContents(); self::assertSame( $this->trimTrailingWhitespace($expected), $this->trimTrailingWhitespace($rendered) ); } } /** * @param 'render'|'renderAll' $renderMethod * @param Format::* $format * * @dataProvider getRenderTests */ public function testRender( string $file, Parser $parser, string $renderMethod, string $format, string $rst, string $expected, bool $useIndenter = true ): void { $expectedLines = explode("\n", $expected); $firstLine = $expectedLines[0]; if (strpos($firstLine, 'Exception:') === 0) { /** @psalm-var class-string */ $exceptionClass = str_replace('Exception: ', '', $firstLine); $this->expectException($exceptionClass); $expectedExceptionMessage = $expectedLines; unset($expectedExceptionMessage[0]); $expectedExceptionMessage = implode("\n", $expectedExceptionMessage); $this->expectExceptionMessage($expectedExceptionMessage); } $document = $parser->parse($rst); $rendered = $document->$renderMethod(); if ($format === Format::HTML && $useIndenter) { $indenter = new Indenter(); $rendered = $indenter->indent($rendered); } self::assertSame( $this->trimTrailingWhitespace($expected), $this->trimTrailingWhitespace($rendered) ); } /** @return iterable */ public function getRenderTests(): iterable { $tests = []; foreach ($this->findSubDirectories(__DIR__ . '/tests/render') as $dir) { $rstFilename = $dir->getPathname() . '/' . $dir->getFilename() . '.rst'; if (! file_exists($rstFilename)) { throw new Exception(sprintf('Could not find functional test file "%s"', $rstFilename)); } $rst = file_get_contents($rstFilename); assert(is_string($rst)); $basename = $dir->getFilename(); foreach ($this->findRstFiles($dir) as $file) { $format = $file->getExtension(); if (! in_array($format, [Format::HTML, Format::LATEX], true)) { throw new Exception(sprintf('Unexpected file extension in "%s"', $file->getPathname())); } if (strpos($file->getFilename(), $dir->getFilename()) !== 0) { throw new Exception(sprintf('Test filename "%s" does not match directory name', $file->getPathname())); } $renderMethod = in_array($basename, self::RENDER_DOCUMENT_FILES, true) ? 'renderDocument' : 'render'; yield $basename . '_' . $format => [ $basename, $this->getParser($format, __DIR__ . '/tests/render/' . $basename), $renderMethod, $format, $rst, trim($file->getContents()), ! in_array($basename, self::SKIP_INDENTER_FILES, true), ]; } } } /** @return iterable */ public function getBuildTests(): iterable { foreach ($this->findSubDirectories(__DIR__ . '/tests/build') as $dir) { $rstFilename = $dir->getPathname() . '/index.rst'; if (! file_exists($rstFilename)) { throw new Exception(sprintf('Could not find functional test file "%s"', $rstFilename)); } $basename = $dir->getFilename(); foreach ($this->findRstFiles($dir) as $file) { $format = $file->getExtension(); if (! in_array($format, [Format::HTML, Format::LATEX], true)) { throw new Exception(sprintf('Unexpected file extension in "%s"', $file->getPathname())); } if (strpos($file->getFilename(), 'index') !== 0) { throw new Exception(sprintf('Test filename "%s" does not match index', $file->getPathname())); } yield $basename . '_' . $format => [ $basename, $this->getParser($format, __DIR__ . '/tests/build/' . $basename), $format, trim($file->getContents()), ]; } } } /** @return iterable */ private function findSubDirectories(string $directory): iterable { $finder = new Finder(); return $finder ->directories() ->in($directory); } /** @return iterable */ private function findRstFiles(SplFileInfo $dir): iterable { $fileFinder = new Finder(); return $fileFinder ->files() ->in($dir->getPathname()) ->notName('*.rst'); } /** @param Format::* $format */ private function getParser(string $format, string $currentDirectory): Parser { $configuration = new Configuration(); $configuration->setFileExtension($format); $configuration->silentOnError(true); $kernel = new Kernel($configuration); $parser = new Parser($kernel); $environment = $parser->getEnvironment(); $environment->setCurrentDirectory($currentDirectory); return $parser; } private function trimTrailingWhitespace(string $string): string { $lines = explode("\n", $string); $lines = array_map(static function (string $line): string { return rtrim($line); }, $lines); return trim(implode("\n", $lines)); } }