mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-14 19:36:43 +00:00
Merge branch '3.x' into 4.x
* 3.x: Remove Drupal integration tests Do not add : void for test methods Fix deprecated PHP CS Fixer rules Replace FQCN with use statements in SandboxTest Fix CS # Conflicts: # .github/workflows/ci.yml # tests/Extension/SandboxTest.php
This commit is contained in:
@@ -98,38 +98,6 @@ jobs:
|
||||
LANG: 'en_US.UTF-8'
|
||||
run: phpunit
|
||||
|
||||
integration-tests:
|
||||
if: "false" # TODO re-enable that job when Drupal does not use features deprecated in 3.x anymore
|
||||
needs:
|
||||
- 'tests'
|
||||
|
||||
name: "Integration tests with PHP ${{ matrix.php-version }}"
|
||||
|
||||
runs-on: 'ubuntu-latest'
|
||||
|
||||
continue-on-error: true
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- '8.2'
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: "Install PHP with extensions"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
coverage: "none"
|
||||
extensions: "gd, pdo_sqlite, uuid"
|
||||
php-version: ${{ matrix.php-version }}
|
||||
ini-values: memory_limit=-1
|
||||
tools: composer:v2
|
||||
|
||||
- run: bash ./tests/drupal_test.sh
|
||||
shell: "bash"
|
||||
|
||||
phpstan:
|
||||
name: "PHPStan"
|
||||
|
||||
|
||||
+21
-2
@@ -8,12 +8,11 @@ return (new Config())
|
||||
->setRules([
|
||||
'@Symfony' => true,
|
||||
'@Symfony:risky' => true,
|
||||
'@PHPUnit75Migration:risky' => true,
|
||||
'@PHPUnit7x5Migration:risky' => true,
|
||||
'php_unit_dedicate_assert' => ['target' => '5.6'],
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'php_unit_fqcn_annotation' => true,
|
||||
'no_unreachable_default_argument_value' => false,
|
||||
'braces' => ['allow_single_line_closure' => true],
|
||||
'heredoc_to_nowdoc' => false,
|
||||
'single_line_throw' => false,
|
||||
'phpdoc_to_comment' => ['ignored_tags' => ['var']],
|
||||
@@ -21,6 +20,26 @@ return (new Config())
|
||||
'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'],
|
||||
'no_superfluous_phpdoc_tags' => ['allow_mixed' => true],
|
||||
])
|
||||
->setRuleCustomisationPolicy(new class implements PhpCsFixer\Config\RuleCustomisationPolicyInterface {
|
||||
public function getPolicyVersionForCache(): string
|
||||
{
|
||||
return hash_file('xxh128', __FILE__);
|
||||
}
|
||||
|
||||
public function getRuleCustomisers(): array
|
||||
{
|
||||
return [
|
||||
'void_return' => static function (SplFileInfo $file) {
|
||||
// temporary hack due to bug: https://github.com/symfony/symfony/issues/62734
|
||||
if (!$file instanceof Symfony\Component\Finder\SplFileInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !str_contains($file->getRelativePathname(), '/Tests/');
|
||||
},
|
||||
];
|
||||
}
|
||||
})
|
||||
->setRiskyAllowed(true)
|
||||
->setParallelConfig(ParallelConfigFactory::detect())
|
||||
->setFinder((new Finder())->in(__DIR__))
|
||||
|
||||
@@ -34,7 +34,11 @@ use Twig\Sandbox\SecurityNotAllowedMethodError;
|
||||
use Twig\Sandbox\SecurityNotAllowedPropertyError;
|
||||
use Twig\Sandbox\SecurityNotAllowedTagError;
|
||||
use Twig\Sandbox\SecurityPolicy;
|
||||
use Twig\Sandbox\SourcePolicyInterface;
|
||||
use Twig\Source;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\TwigTest;
|
||||
|
||||
class SandboxTest extends TestCase
|
||||
{
|
||||
@@ -252,7 +256,7 @@ class SandboxTest extends TestCase
|
||||
public function testSandboxUnallowedToString($template)
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => $template], ['if', 'do', 'for', 'set'], ['upper', 'join', 'replace', 'format', 'split'], [FooObject::class => 'getAnotherFooObject'], [], ['random', 'range', 'my_func']);
|
||||
$twig->addFunction(new \Twig\TwigFunction('my_func', fn ($a) => (string) $a));
|
||||
$twig->addFunction(new TwigFunction('my_func', static fn ($a) => (string) $a));
|
||||
try {
|
||||
$twig->load('index')->render(self::$params);
|
||||
$this->fail('Sandbox throws a SecurityError exception if an unallowed method "__toString()" method is called in the template');
|
||||
@@ -329,7 +333,7 @@ class SandboxTest extends TestCase
|
||||
public function testSandboxBlocksToStringOnFunctionReturn()
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{{ make_obj() }}'], [], [], [], [], ['make_obj']);
|
||||
$twig->addFunction(new \Twig\TwigFunction('make_obj', fn () => new FooObject()));
|
||||
$twig->addFunction(new TwigFunction('make_obj', static fn () => new FooObject()));
|
||||
try {
|
||||
$twig->load('index')->render([]);
|
||||
$this->fail('Sandbox throws a SecurityError exception if __toString is called on the return of an allowed function');
|
||||
@@ -342,7 +346,7 @@ class SandboxTest extends TestCase
|
||||
public function testSandboxBlocksToStringOnFilterReturn()
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{{ "x"|to_obj }}'], [], ['to_obj']);
|
||||
$twig->addFilter(new \Twig\TwigFilter('to_obj', fn () => new FooObject()));
|
||||
$twig->addFilter(new TwigFilter('to_obj', static fn () => new FooObject()));
|
||||
try {
|
||||
$twig->load('index')->render([]);
|
||||
$this->fail('Sandbox throws a SecurityError exception if __toString is called on the return of an allowed filter');
|
||||
@@ -646,6 +650,7 @@ EOF
|
||||
if (str_contains($message, 'BAD-MACRO-REF')) {
|
||||
$triggered = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}, \E_USER_NOTICE | \E_USER_WARNING);
|
||||
try {
|
||||
@@ -676,6 +681,7 @@ EOF
|
||||
if (str_contains($message, 'BAD-IMPORT-REF')) {
|
||||
$triggered = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}, \E_USER_NOTICE | \E_USER_WARNING);
|
||||
try {
|
||||
@@ -835,7 +841,7 @@ EOF
|
||||
|
||||
public function testSandboxSourcePolicyEnableReturningFalse()
|
||||
{
|
||||
$twig = $this->getEnvironment(false, [], self::$templates, [], [], [], [], [], new class implements \Twig\Sandbox\SourcePolicyInterface {
|
||||
$twig = $this->getEnvironment(false, [], self::$templates, [], [], [], [], [], new class implements SourcePolicyInterface {
|
||||
public function enableSandbox(Source $source): bool
|
||||
{
|
||||
return '1_basic' != $source->getName();
|
||||
@@ -846,7 +852,7 @@ EOF
|
||||
|
||||
public function testSandboxSourcePolicyEnableReturningTrue()
|
||||
{
|
||||
$twig = $this->getEnvironment(false, [], self::$templates, [], [], [], [], [], new class implements \Twig\Sandbox\SourcePolicyInterface {
|
||||
$twig = $this->getEnvironment(false, [], self::$templates, [], [], [], [], [], new class implements SourcePolicyInterface {
|
||||
public function enableSandbox(Source $source): bool
|
||||
{
|
||||
return '1_basic' === $source->getName();
|
||||
@@ -858,7 +864,7 @@ EOF
|
||||
|
||||
public function testSandboxSourcePolicyFalseDoesntOverrideOtherEnables()
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], self::$templates, [], [], [], [], [], new class implements \Twig\Sandbox\SourcePolicyInterface {
|
||||
$twig = $this->getEnvironment(true, [], self::$templates, [], [], [], [], [], new class implements SourcePolicyInterface {
|
||||
public function enableSandbox(Source $source): bool
|
||||
{
|
||||
return false;
|
||||
@@ -870,7 +876,7 @@ EOF
|
||||
|
||||
public function testSourcePolicyAllowsClosureInArrow()
|
||||
{
|
||||
$sourcePolicy = new class implements \Twig\Sandbox\SourcePolicyInterface {
|
||||
$sourcePolicy = new class implements SourcePolicyInterface {
|
||||
public function enableSandbox(Source $source): bool
|
||||
{
|
||||
return true;
|
||||
@@ -884,7 +890,7 @@ EOF
|
||||
public function testNeedsIsSandboxedFilterReceivesTrueWhenSandboxed()
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{{ "foo"|sandbox_aware }}'], [], ['sandbox_aware']);
|
||||
$twig->addFilter(new \Twig\TwigFilter('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
$twig->addFilter(new TwigFilter('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
return $value.':'.($isSandboxed ? 'on' : 'off');
|
||||
}, ['needs_is_sandboxed' => true]));
|
||||
|
||||
@@ -894,7 +900,7 @@ EOF
|
||||
public function testNeedsIsSandboxedFilterReceivesFalseWhenNotSandboxed()
|
||||
{
|
||||
$twig = $this->getEnvironment(false, [], ['index' => '{{ "foo"|sandbox_aware }}']);
|
||||
$twig->addFilter(new \Twig\TwigFilter('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
$twig->addFilter(new TwigFilter('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
return $value.':'.($isSandboxed ? 'on' : 'off');
|
||||
}, ['needs_is_sandboxed' => true]));
|
||||
|
||||
@@ -906,13 +912,13 @@ EOF
|
||||
$twig = $this->getEnvironment(false, [], [
|
||||
'in' => '{{ "foo"|sandbox_aware }}',
|
||||
'out' => '{{ "foo"|sandbox_aware }}',
|
||||
], [], ['sandbox_aware'], [], [], [], new class implements \Twig\Sandbox\SourcePolicyInterface {
|
||||
], [], ['sandbox_aware'], [], [], [], new class implements SourcePolicyInterface {
|
||||
public function enableSandbox(Source $source): bool
|
||||
{
|
||||
return 'in' === $source->getName();
|
||||
}
|
||||
});
|
||||
$twig->addFilter(new \Twig\TwigFilter('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
$twig->addFilter(new TwigFilter('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
return $value.':'.($isSandboxed ? 'on' : 'off');
|
||||
}, ['needs_is_sandboxed' => true]));
|
||||
|
||||
@@ -924,7 +930,7 @@ EOF
|
||||
{
|
||||
$loader = new ArrayLoader(['index' => '{{ sandbox_aware("foo") }}']);
|
||||
$twig = new Environment($loader, ['debug' => true, 'cache' => false, 'autoescape' => false]);
|
||||
$twig->addFunction(new \Twig\TwigFunction('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
$twig->addFunction(new TwigFunction('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
return $value.':'.($isSandboxed ? 'on' : 'off');
|
||||
}, ['needs_is_sandboxed' => true]));
|
||||
|
||||
@@ -934,7 +940,7 @@ EOF
|
||||
public function testNeedsIsSandboxedTestReceivesTrueWhenSandboxed()
|
||||
{
|
||||
$twig = $this->getEnvironment(true, [], ['index' => '{{ "foo" is sandbox_aware ? "on" : "off" }}']);
|
||||
$twig->addTest(new \Twig\TwigTest('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
$twig->addTest(new TwigTest('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
return $isSandboxed && 'foo' === $value;
|
||||
}, ['needs_is_sandboxed' => true]));
|
||||
|
||||
@@ -944,7 +950,7 @@ EOF
|
||||
public function testNeedsIsSandboxedTestReceivesFalseWhenNotSandboxed()
|
||||
{
|
||||
$twig = $this->getEnvironment(false, [], ['index' => '{{ "foo" is sandbox_aware ? "on" : "off" }}']);
|
||||
$twig->addTest(new \Twig\TwigTest('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
$twig->addTest(new TwigTest('sandbox_aware', static function (bool $isSandboxed, string $value) {
|
||||
return !$isSandboxed && 'foo' === $value;
|
||||
}, ['needs_is_sandboxed' => true]));
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
REPO=`pwd`
|
||||
cd /tmp
|
||||
rm -rf drupal-twig-test
|
||||
composer create-project --no-interaction drupal/recommended-project:10.1.x-dev drupal-twig-test
|
||||
cd drupal-twig-test
|
||||
(cd vendor/twig && rm -rf twig && ln -sf $REPO twig)
|
||||
composer dump-autoload
|
||||
php ./web/core/scripts/drupal install --no-interaction demo_umami > output
|
||||
perl -p -i -e 's/^([A-Za-z]+)\: (.+)$/export DRUPAL_\1=\2/' output
|
||||
source output
|
||||
#echo '$config["system.logging"]["error_level"] = "verbose";' >> web/sites/default/settings.php
|
||||
|
||||
wget https://get.symfony.com/cli/installer -O - | bash
|
||||
export PATH="$HOME/.symfony5/bin:$PATH"
|
||||
symfony server:start -d --no-tls
|
||||
|
||||
curl -LsS -o blackfire-player.phar https://get.blackfire.io/blackfire-player-v1.31.0.phar
|
||||
chmod +x blackfire-player.phar
|
||||
cat > drupal-tests.bkf <<EOF
|
||||
name "Drupal tests"
|
||||
|
||||
scenario
|
||||
name "homepage"
|
||||
set name "admin"
|
||||
set pass "pass"
|
||||
|
||||
visit url('/')
|
||||
expect status_code() == 200
|
||||
click link('Articles')
|
||||
expect status_code() == 200
|
||||
click link('Dairy-free and delicious milk chocolate')
|
||||
expect body() matches "/Dairy\-free milk chocolate is made in largely the same way as regular chocolate/"
|
||||
expect status_code() == 200
|
||||
click link('Log in')
|
||||
expect status_code() == 200
|
||||
submit button("Log in")
|
||||
param name name
|
||||
param pass pass
|
||||
expect status_code() == 303
|
||||
follow
|
||||
expect status_code() == 200
|
||||
click link('Structure')
|
||||
expect status_code() == 200
|
||||
EOF
|
||||
./blackfire-player.phar run drupal-tests.bkf --endpoint=`symfony var:export SYMFONY_DEFAULT_ROUTE_URL` --variable name=$DRUPAL_Username --variable pass=$DRUPAL_Password
|
||||
symfony server:stop
|
||||
Reference in New Issue
Block a user