mirror of
https://github.com/twigphp/Twig.git
synced 2026-10-10 13:55:37 +00:00
04ace9dba0
* 3.x: Handle single-node child template bodies in cleanup Keep captured block definitions supported Clarify captured block deprecation wording Simplify correctness visitor checks Move extends validation into correctness visitor Fix correctness visitor regressions Fix test assertions that did not verify the intended behavior Address review: fix block-nesting checks in CorrectnessNodeVisitor Move the extends-in-block and extends-in-macro errors into the CorrectnessNodeVisitor Introduce a CorrectnessNodeVisitor to validate that templates are semantically correct Mark Markup as final Allow calling a macro with a dynamic name via the dot operator Add an allow-list for tests to the sandbox security policy Fix markdown_to_html mangling content that starts with a blank line # Conflicts: # CHANGELOG # doc/deprecated.rst # doc/sandbox.rst # src/ExpressionParser/Infix/DotExpressionParser.php # src/Extension/CoreExtension.php # src/Markup.php # src/Node/CheckSecurityNode.php # src/Node/Expression/Filter/DefaultFilter.php # src/Node/Expression/NullCoalesceExpression.php # src/Node/IfNode.php # src/NodeVisitor/SandboxNodeVisitor.php # src/Parser.php # src/Sandbox/SecurityPolicy.php # tests/Extension/SandboxTest.php # tests/ParserTest.php
138 lines
4.3 KiB
PHP
138 lines
4.3 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of Twig.
|
|
*
|
|
* (c) Fabien Potencier
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Twig\Extra\Markdown\Tests;
|
|
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Twig\Environment;
|
|
use Twig\Extra\Markdown\DefaultMarkdown;
|
|
use Twig\Extra\Markdown\ErusevMarkdown;
|
|
use Twig\Extra\Markdown\LeagueMarkdown;
|
|
use Twig\Extra\Markdown\MarkdownExtension;
|
|
use Twig\Extra\Markdown\MarkdownInterface;
|
|
use Twig\Extra\Markdown\MarkdownRuntime;
|
|
use Twig\Extra\Markdown\MichelfMarkdown;
|
|
use Twig\Loader\ArrayLoader;
|
|
use Twig\RuntimeLoader\RuntimeLoaderInterface;
|
|
|
|
class FunctionalTest extends TestCase
|
|
{
|
|
#[DataProvider('getMarkdownTests')]
|
|
public function testMarkdown(string $template, string $expected)
|
|
{
|
|
foreach ([LeagueMarkdown::class, ErusevMarkdown::class, /* MichelfMarkdown::class, */ DefaultMarkdown::class] as $class) {
|
|
$twig = new Environment(new ArrayLoader([
|
|
'index' => $template,
|
|
'html' => <<<EOF
|
|
Hello
|
|
=====
|
|
|
|
Great!
|
|
EOF,
|
|
]));
|
|
$twig->addExtension(new MarkdownExtension());
|
|
$twig->addRuntimeLoader(new class($class) implements RuntimeLoaderInterface {
|
|
private $class;
|
|
|
|
public function __construct(string $class)
|
|
{
|
|
$this->class = $class;
|
|
}
|
|
|
|
public function load(string $c): ?object
|
|
{
|
|
return MarkdownRuntime::class === $c ? new $c(new $this->class()) : null;
|
|
}
|
|
});
|
|
$this->assertMatchesRegularExpression('{'.$expected.'}m', trim($twig->render('index')));
|
|
}
|
|
}
|
|
|
|
public static function getMarkdownTests()
|
|
{
|
|
return [
|
|
[<<<EOF
|
|
{% apply markdown_to_html %}
|
|
Hello
|
|
=====
|
|
|
|
Great!
|
|
{% endapply %}
|
|
EOF, "<h1>Hello</h1>\n+<p>Great!</p>"],
|
|
[<<<EOF
|
|
{% apply markdown_to_html %}
|
|
Hello
|
|
=====
|
|
|
|
Great!
|
|
{% endapply %}
|
|
EOF, "<h1>Hello</h1>\n+<p>Great!</p>"],
|
|
["{{ include('html')|markdown_to_html }}", "<h1>Hello</h1>\n+<p>Great!</p>"],
|
|
[<<<EOF
|
|
{% apply markdown_to_html %}
|
|
|
|
Paragraph 1
|
|
|
|
Paragraph 2
|
|
{% endapply %}
|
|
EOF, "<p>Paragraph 1</p>\n+<p>Paragraph 2</p>"],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider getIndentationTests
|
|
*/
|
|
public function testStripsCommonIndentation(string $body, string $expected)
|
|
{
|
|
$runtime = new MarkdownRuntime(new class implements MarkdownInterface {
|
|
public function convert(string $body): string
|
|
{
|
|
return $body;
|
|
}
|
|
});
|
|
|
|
$this->assertSame($expected, $runtime->convert($body));
|
|
}
|
|
|
|
public static function getIndentationTests()
|
|
{
|
|
return [
|
|
'leading blank line keeps blank lines' => ["\nParagraph 1\n\nParagraph 2", "\nParagraph 1\n\nParagraph 2"],
|
|
'common indentation is removed' => ["\n Hello\n =====\n\n Great!\n", "\nHello\n=====\n\nGreat!\n"],
|
|
'minimal common indentation is removed' => [" a\n b\n", "a\n b\n"],
|
|
'indented code block before non-indented prose is preserved' => [" Code\n\nParagraph\n", " Code\n\nParagraph\n"],
|
|
'tab indentation is removed' => ["\tHello\n\tGreat!\n", "Hello\nGreat!\n"],
|
|
'mixed tabs and spaces are left untouched' => ["\ta\n b\n", "\ta\n b\n"],
|
|
'blank lines are ignored when computing indentation' => [" a\n\n b\n", "a\n\nb\n"],
|
|
];
|
|
}
|
|
|
|
public function testMarkdownToHtmlIsNotSafeInJsContext()
|
|
{
|
|
$twig = new Environment(new ArrayLoader([
|
|
'index' => "{% autoescape 'js' %}{{ '# Hello'|markdown_to_html }}{% endautoescape %}",
|
|
]));
|
|
$twig->addExtension(new MarkdownExtension());
|
|
$twig->addRuntimeLoader(new class implements RuntimeLoaderInterface {
|
|
public function load(string $c): ?object
|
|
{
|
|
return MarkdownRuntime::class === $c ? new $c(new DefaultMarkdown()) : null;
|
|
}
|
|
});
|
|
|
|
$output = $twig->render('index');
|
|
|
|
$this->assertStringNotContainsString('<h1>', $output);
|
|
$this->assertMatchesRegularExpression('{\\\\u003[Cc]h1\\\\u003[Ee]Hello\\\\u003[Cc]\\\\/h1\\\\u003[Ee]}', $output);
|
|
}
|
|
}
|