* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace League\CommonMark\Tests\Functional\Extension\HeadingPermalink; use League\CommonMark\Environment\Environment; use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension; use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkProcessor; use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkRenderer; use League\CommonMark\MarkdownConverter; use League\CommonMark\Parser\MarkdownParser; use League\CommonMark\Xml\XmlRenderer; use League\Config\Exception\InvalidConfigurationException; use PHPUnit\Framework\TestCase; final class HeadingPermalinkExtensionTest extends TestCase { /** * @dataProvider dataProviderForTestHeadingPermalinksWithDefaultOptions */ public function testHeadingPermalinksWithDefaultOptions(string $input, string $expected): void { $environment = new Environment(); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $converter = new MarkdownConverter($environment); $this->assertEquals($expected, \trim((string) $converter->convert($input))); } public function dataProviderForTestHeadingPermalinksWithDefaultOptions(): \Generator { yield ['# Hello World!', \sprintf('

Hello World!

', HeadingPermalinkRenderer::DEFAULT_SYMBOL)]; yield ['# Hello *World*', \sprintf('

Hello World

', HeadingPermalinkRenderer::DEFAULT_SYMBOL)]; yield ['# Hello `World`', \sprintf('

Hello World

', HeadingPermalinkRenderer::DEFAULT_SYMBOL)]; yield ["Test\n----", \sprintf('

Test

', HeadingPermalinkRenderer::DEFAULT_SYMBOL)]; yield ["# Hello World!\n\n# Hello World!", \sprintf("

%sHello World!

\n

%sHello World!

", HeadingPermalinkRenderer::DEFAULT_SYMBOL, HeadingPermalinkRenderer::DEFAULT_SYMBOL)]; } /** * @dataProvider dataProviderForTestHeadingPermalinksWithCustomOptions */ public function testHeadingPermalinksWithCustomOptions(string $input, string $expected): void { $environment = new Environment([ 'heading_permalink' => [ 'html_class' => 'custom-class', 'id_prefix' => 'custom-id-prefix', 'fragment_prefix' => 'custom-fragment-prefix', // Ensure multiple characters are allowed (including multibyte) and special HTML characters are escaped. 'symbol' => '¶ 🦄️ <3 You', 'insert' => HeadingPermalinkProcessor::INSERT_AFTER, 'title' => 'Link', 'aria_hidden' => false, ], ]); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $converter = new MarkdownConverter($environment); $this->assertEquals($expected, \trim((string) $converter->convert($input))); } public function dataProviderForTestHeadingPermalinksWithCustomOptions(): \Generator { yield ['# Hello World!', '

Hello World!¶ 🦄️ <3 You

']; yield ['# Hello *World*', '

Hello World¶ 🦄️ <3 You

']; yield ["Test\n----", '

Test¶ 🦄️ <3 You

']; } public function testHeadingPermalinksWithEmptyPrefixes(): void { $environment = new Environment([ 'heading_permalink' => [ 'id_prefix' => '', 'fragment_prefix' => '', ], ]); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $converter = new MarkdownConverter($environment); $input = '# Hello World!'; $expected = \sprintf('

Hello World!

', HeadingPermalinkRenderer::DEFAULT_SYMBOL); $this->assertEquals($expected, \trim((string) $converter->convert($input))); } public function testHeadingPermalinksWithEmptySymbol(): void { $environment = new Environment([ 'heading_permalink' => [ 'symbol' => '', 'id_prefix' => '', 'fragment_prefix' => '', ], ]); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $converter = new MarkdownConverter($environment); $input = '# Hello World!'; $expected = '

Hello World!

'; $this->assertEquals($expected, \trim((string) $converter->convert($input))); } public function testHeadingPermalinksWithInvalidInsertConfigurationValue(): void { $this->expectException(InvalidConfigurationException::class); $environment = new Environment([ 'heading_permalink' => [ 'insert' => 'invalid value here', ], ]); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $converter = new MarkdownConverter($environment); $converter->convert('# This will fail'); } public function testWithCustomLevels(): void { $environment = new Environment([ 'heading_permalink' => [ 'min_heading_level' => 2, 'max_heading_level' => 3, ], ]); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $converter = new MarkdownConverter($environment); $input = <<1

2

3

4

EOT; $this->assertEquals($expected, \trim((string) $converter->convert($input))); } public function testHeadingPermalinksWithApplyIdToHeading(): void { $environment = new Environment([ 'heading_permalink' => [ 'apply_id_to_heading' => true, ], ]); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $converter = new MarkdownConverter($environment); $input = '# Hello World!'; $expected = \sprintf('

Hello World!

', HeadingPermalinkRenderer::DEFAULT_SYMBOL); $this->assertEquals($expected, \trim((string) $converter->convert($input))); } public function testHeadingPermalinksWithApplyIdToHeadingAndClass(): void { $environment = new Environment([ 'heading_permalink' => [ 'apply_id_to_heading' => true, 'heading_class' => 'heading-anchor', ], ]); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $converter = new MarkdownConverter($environment); $input = '# Hello World!'; $expected = \sprintf('

Hello World!

', HeadingPermalinkRenderer::DEFAULT_SYMBOL); $this->assertEquals($expected, \trim((string) $converter->convert($input))); } public function testHeadingPermalinksWithApplyIdToHeadingWithoutLink(): void { $environment = new Environment([ 'heading_permalink' => [ 'insert' => HeadingPermalinkProcessor::INSERT_NONE, 'apply_id_to_heading' => true, 'heading_class' => 'heading-anchor', ], ]); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $converter = new MarkdownConverter($environment); $input = '# Hello World!'; $expected = '

Hello World!

'; $this->assertEquals($expected, \trim((string) $converter->convert($input))); } public function testXml(): void { $md = '# Hello *World*'; $expectedXml = << Hello World XML; $environment = new Environment([ 'heading_permalink' => [ 'id_prefix' => '', 'fragment_prefix' => '', ], ]); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new HeadingPermalinkExtension()); $document = (new MarkdownParser($environment))->parse($md); $this->assertSame($expectedXml, \rtrim((new XmlRenderer($environment))->renderDocument($document)->getContent())); } }