Merge branch '4.4' into 5.1
* 4.4: [HttpKernel] Adjust tests to new "class not found" error message format. Don't call createMock with an array of interfaces. [FrameworkBundle] Fix Tests on PHPUnit 9.3. [WebProfilerBundle] Fix Tests on PHPUnit 9.3. esmtp error not being thrown properly [Yaml Parser] fixed Parser to skip comments when inlining sequences [DI] fix generating preload file when cache_dir is outside project_dir Fix CacheCollectorPass with decorated cache pools [PhpUnitBridge] CoverageListenerTrait update for PHPUnit 8.5/9.x Remove invalid instantiation declaration [PropertyInfo] Fix typed collections in PHP 7.4
This commit is contained in:
commit
0bdef0a996
@ -70,7 +70,7 @@ class EntityUserProviderTest extends TestCase
|
||||
{
|
||||
$user = new User(1, 1, 'user1');
|
||||
|
||||
$repository = $this->createMock([ObjectRepository::class, UserLoaderInterface::class]);
|
||||
$repository = $this->createMock(UserLoaderRepository::class);
|
||||
$repository
|
||||
->expects($this->once())
|
||||
->method('loadUserByUsername')
|
||||
@ -156,7 +156,7 @@ class EntityUserProviderTest extends TestCase
|
||||
|
||||
public function testLoadUserByUserNameShouldLoadUserWhenProperInterfaceProvided()
|
||||
{
|
||||
$repository = $this->createMock([ObjectRepository::class, UserLoaderInterface::class]);
|
||||
$repository = $this->createMock(UserLoaderRepository::class);
|
||||
$repository->expects($this->once())
|
||||
->method('loadUserByUsername')
|
||||
->with('name')
|
||||
@ -189,7 +189,7 @@ class EntityUserProviderTest extends TestCase
|
||||
{
|
||||
$user = new User(1, 1, 'user1');
|
||||
|
||||
$repository = $this->createMock([interface_exists(ObjectRepository::class) ? ObjectRepository::class : LegacyObjectRepository::class, PasswordUpgraderInterface::class]);
|
||||
$repository = $this->createMock(PasswordUpgraderRepository::class);
|
||||
$repository->expects($this->once())
|
||||
->method('upgradePassword')
|
||||
->with($user, 'foobar');
|
||||
@ -233,3 +233,11 @@ class EntityUserProviderTest extends TestCase
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class UserLoaderRepository implements ObjectRepository, UserLoaderInterface
|
||||
{
|
||||
}
|
||||
|
||||
abstract class PasswordUpgraderRepository implements ObjectRepository, PasswordUpgraderInterface
|
||||
{
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Bridge\PhpUnit\Legacy;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\Warning;
|
||||
use PHPUnit\Util\Annotation\Registry;
|
||||
use PHPUnit\Util\Test;
|
||||
|
||||
/**
|
||||
@ -66,9 +67,6 @@ class CoverageListenerTrait
|
||||
return;
|
||||
}
|
||||
|
||||
$r = new \ReflectionProperty(Test::class, 'annotationCache');
|
||||
$r->setAccessible(true);
|
||||
|
||||
$covers = $sutFqcn;
|
||||
if (!\is_array($sutFqcn)) {
|
||||
$covers = [$sutFqcn];
|
||||
@ -78,15 +76,42 @@ class CoverageListenerTrait
|
||||
}
|
||||
}
|
||||
|
||||
if (class_exists(Registry::class)) {
|
||||
$this->addCoversForDocBlockInsideRegistry($test, $covers);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addCoversForClassToAnnotationCache($test, $covers);
|
||||
}
|
||||
|
||||
private function addCoversForClassToAnnotationCache($test, $covers)
|
||||
{
|
||||
$r = new \ReflectionProperty(Test::class, 'annotationCache');
|
||||
$r->setAccessible(true);
|
||||
|
||||
$cache = $r->getValue();
|
||||
$cache = array_replace_recursive($cache, [
|
||||
\get_class($test) => [
|
||||
'covers' => $covers,
|
||||
],
|
||||
]);
|
||||
|
||||
$r->setValue(Test::class, $cache);
|
||||
}
|
||||
|
||||
private function addCoversForDocBlockInsideRegistry($test, $covers)
|
||||
{
|
||||
$docBlock = Registry::getInstance()->forClassName(\get_class($test));
|
||||
|
||||
$symbolAnnotations = new \ReflectionProperty($docBlock, 'symbolAnnotations');
|
||||
$symbolAnnotations->setAccessible(true);
|
||||
|
||||
$symbolAnnotations->setValue($docBlock, array_replace($docBlock->symbolAnnotations(), [
|
||||
'covers' => $covers,
|
||||
]));
|
||||
}
|
||||
|
||||
private function findSutFqcn($test)
|
||||
{
|
||||
if ($this->sutFqcnResolver) {
|
||||
|
@ -71,7 +71,7 @@ class WebTestCaseTest extends TestCase
|
||||
{
|
||||
$this->getResponseTester(new Response('', 302, ['Location' => 'https://example.com/']))->assertResponseRedirects('https://example.com/', 302);
|
||||
$this->expectException(AssertionFailedError::class);
|
||||
$this->expectExceptionMessage('is redirected and has header "Location" with value "https://example.com/" and status code is 301.');
|
||||
$this->expectExceptionMessageMatches('#(:?\( )?is redirected and has header "Location" with value "https://example\.com/" (:?\) )?and status code is 301\.#');
|
||||
$this->getResponseTester(new Response('', 302))->assertResponseRedirects('https://example.com/', 301);
|
||||
}
|
||||
|
||||
|
@ -382,10 +382,12 @@ class ProfilerControllerTest extends WebTestCase
|
||||
->with($profile->getToken())
|
||||
->willReturn($profile);
|
||||
|
||||
$collectorsNames = array_keys($profile->getCollectors());
|
||||
|
||||
$profiler
|
||||
->expects($this->atLeastOnce())
|
||||
->method('has')
|
||||
->with($this->logicalXor($collectorsNames = array_keys($profile->getCollectors())))
|
||||
->with($this->logicalXor(...$collectorsNames))
|
||||
->willReturn(true);
|
||||
|
||||
$expectedTemplate = 'expected_template.html.twig';
|
||||
|
@ -47,15 +47,13 @@ class CacheCollectorPass implements CompilerPassInterface
|
||||
}
|
||||
|
||||
foreach ($container->findTaggedServiceIds($this->cachePoolTag) as $id => $attributes) {
|
||||
$this->addToCollector($id, $container);
|
||||
$poolName = $attributes[0]['name'] ?? $id;
|
||||
|
||||
if (($attributes[0]['name'] ?? $id) !== $id) {
|
||||
$this->addToCollector($attributes[0]['name'], $container);
|
||||
}
|
||||
$this->addToCollector($id, $poolName, $container);
|
||||
}
|
||||
}
|
||||
|
||||
private function addToCollector(string $id, ContainerBuilder $container)
|
||||
private function addToCollector(string $id, string $name, ContainerBuilder $container)
|
||||
{
|
||||
$definition = $container->getDefinition($id);
|
||||
if ($definition->isAbstract()) {
|
||||
@ -77,7 +75,7 @@ class CacheCollectorPass implements CompilerPassInterface
|
||||
$container->setDefinition($id, $recorder);
|
||||
|
||||
// Tell the collector to add the new instance
|
||||
$collectorDefinition->addMethodCall('addInstance', [$id, new Reference($id)]);
|
||||
$collectorDefinition->addMethodCall('addInstance', [$name, new Reference($id)]);
|
||||
$collectorDefinition->setPublic(false);
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\Cache\Adapter\ChainAdapter;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
|
||||
use Symfony\Component\Cache\Tests\Fixtures\PrunableAdapter;
|
||||
|
||||
/**
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
@ -189,7 +189,7 @@ class ChainAdapterTest extends AdapterTestCase
|
||||
|
||||
private function getPruneableMock(): AdapterInterface
|
||||
{
|
||||
$pruneable = $this->createMock([PruneableInterface::class, AdapterInterface::class]);
|
||||
$pruneable = $this->createMock(PrunableAdapter::class);
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
@ -201,7 +201,7 @@ class ChainAdapterTest extends AdapterTestCase
|
||||
|
||||
private function getFailingPruneableMock(): AdapterInterface
|
||||
{
|
||||
$pruneable = $this->createMock([PruneableInterface::class, AdapterInterface::class]);
|
||||
$pruneable = $this->createMock(PrunableAdapter::class);
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
|
@ -18,7 +18,7 @@ use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
use Symfony\Component\Cache\Tests\Fixtures\PrunableAdapter;
|
||||
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
|
||||
|
||||
/**
|
||||
@ -204,7 +204,7 @@ class TagAwareAdapterTest extends AdapterTestCase
|
||||
*/
|
||||
private function getPruneableMock(): AdapterInterface
|
||||
{
|
||||
$pruneable = $this->createMock([PruneableInterface::class, AdapterInterface::class]);
|
||||
$pruneable = $this->createMock(PrunableAdapter::class);
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
@ -216,7 +216,7 @@ class TagAwareAdapterTest extends AdapterTestCase
|
||||
|
||||
private function getFailingPruneableMock(): AdapterInterface
|
||||
{
|
||||
$pruneable = $this->createMock([PruneableInterface::class, AdapterInterface::class]);
|
||||
$pruneable = $this->createMock(PrunableAdapter::class);
|
||||
|
||||
$pruneable
|
||||
->expects($this->atLeastOnce())
|
||||
|
@ -19,6 +19,8 @@ use Symfony\Component\Cache\Adapter\TraceableAdapter;
|
||||
use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter;
|
||||
use Symfony\Component\Cache\DataCollector\CacheDataCollector;
|
||||
use Symfony\Component\Cache\DependencyInjection\CacheCollectorPass;
|
||||
use Symfony\Component\Cache\Tests\Fixtures\ArrayCache;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
@ -48,16 +50,51 @@ class CacheCollectorPassTest extends TestCase
|
||||
$this->assertEquals([
|
||||
['addInstance', ['fs', new Reference('fs')]],
|
||||
['addInstance', ['tagged_fs', new Reference('tagged_fs')]],
|
||||
['addInstance', ['.php.inner', new Reference('.php.inner')]],
|
||||
['addInstance', ['php', new Reference('php')]],
|
||||
['addInstance', ['php', new Reference('.php.inner')]],
|
||||
], $collector->getMethodCalls());
|
||||
|
||||
$this->assertSame(TraceableAdapter::class, $container->findDefinition('fs')->getClass());
|
||||
$this->assertSame(TraceableTagAwareAdapter::class, $container->getDefinition('tagged_fs')->getClass());
|
||||
|
||||
$this->assertSame(TraceableAdapter::class, $container->findDefinition('.php.inner')->getClass());
|
||||
$this->assertSame(TraceableTagAwareAdapter::class, $container->getDefinition('php')->getClass());
|
||||
$this->assertSame(TagAwareAdapter::class, $container->getDefinition('php')->getClass());
|
||||
|
||||
$this->assertFalse($collector->isPublic(), 'The "data_collector.cache" should be private after processing');
|
||||
}
|
||||
|
||||
public function testProcessCacheObjectsAreDecorated()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$collector = $container->register('data_collector.cache', CacheDataCollector::class);
|
||||
|
||||
$container
|
||||
->register('cache.object', ArrayCache::class)
|
||||
->addTag('cache.pool', ['name' => 'cache.object']);
|
||||
|
||||
$container
|
||||
->register('something_is_decorating_cache_object', TagAwareAdapter::class)
|
||||
->setPublic(true)
|
||||
->setDecoratedService('cache.object');
|
||||
|
||||
$container->register('some_service_using_cache_object', TraceableAdapter::class)
|
||||
->setPublic(true)
|
||||
->addArgument(new Reference('cache.object'));
|
||||
|
||||
$container->addCompilerPass(new CacheCollectorPass(), PassConfig::TYPE_BEFORE_REMOVING);
|
||||
|
||||
$container->compile();
|
||||
$this->assertCount(1, $collector->getMethodCalls());
|
||||
$this->assertEquals(
|
||||
[
|
||||
[
|
||||
'addInstance',
|
||||
[
|
||||
'cache.object',
|
||||
new Reference('something_is_decorating_cache_object'),
|
||||
],
|
||||
],
|
||||
],
|
||||
$collector->getMethodCalls()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Fixtures;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
|
||||
abstract class PrunableAdapter implements AdapterInterface, PruneableInterface
|
||||
{
|
||||
}
|
19
src/Symfony/Component/Cache/Tests/Fixtures/PrunableCache.php
Normal file
19
src/Symfony/Component/Cache/Tests/Fixtures/PrunableCache.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Cache\Tests\Fixtures;
|
||||
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Symfony\Component\Cache\PruneableInterface;
|
||||
|
||||
abstract class PrunableCache implements CacheInterface, PruneableInterface
|
||||
{
|
||||
}
|
@ -326,7 +326,7 @@ EOF;
|
||||
$this->asFiles = false;
|
||||
|
||||
if ($this->preload && null !== $autoloadFile = $this->getAutoloadFile()) {
|
||||
$autoloadFile = substr($this->export($autoloadFile), 2, -1);
|
||||
$autoloadFile = trim($this->export($autoloadFile), '()\\');
|
||||
|
||||
$preloadedFiles = array_reverse($preloadedFiles);
|
||||
$preloadedFiles = implode("';\nrequire __DIR__.'/", $preloadedFiles);
|
||||
@ -2123,9 +2123,7 @@ EOF;
|
||||
|
||||
private function getAutoloadFile(): ?string
|
||||
{
|
||||
if (null === $this->targetDirRegex) {
|
||||
return null;
|
||||
}
|
||||
$file = null;
|
||||
|
||||
foreach (spl_autoload_functions() as $autoloader) {
|
||||
if (!\is_array($autoloader)) {
|
||||
@ -2144,14 +2142,14 @@ EOF;
|
||||
if (0 === strpos($class, 'ComposerAutoloaderInit') && $class::getLoader() === $autoloader[0]) {
|
||||
$file = \dirname((new \ReflectionClass($class))->getFileName(), 2).'/autoload.php';
|
||||
|
||||
if (preg_match($this->targetDirRegex.'A', $file)) {
|
||||
if (null !== $this->targetDirRegex && preg_match($this->targetDirRegex.'A', $file)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function getClasses(Definition $definition, string $id): array
|
||||
|
@ -16,18 +16,6 @@ use Symfony\Component\Form\Extension\Core\DataTransformer\StringToFloatTransform
|
||||
|
||||
class StringToFloatTransformerTest extends TestCase
|
||||
{
|
||||
private $transformer;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->transformer = new StringToFloatTransformer();
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$this->transformer = null;
|
||||
}
|
||||
|
||||
public function provideTransformations(): array
|
||||
{
|
||||
return [
|
||||
|
@ -170,9 +170,9 @@ class ControllerResolverTest extends TestCase
|
||||
$controller = new ControllerTest();
|
||||
|
||||
return [
|
||||
['foo', \Error::class, 'Class \'foo\' not found'],
|
||||
['oof::bar', \Error::class, 'Class \'oof\' not found'],
|
||||
[['oof', 'bar'], \Error::class, 'Class \'oof\' not found'],
|
||||
['foo', \Error::class, \PHP_VERSION_ID < 80000 ? 'Class \'foo\' not found' : 'Class "foo" not found'],
|
||||
['oof::bar', \Error::class, \PHP_VERSION_ID < 80000 ? 'Class \'oof\' not found' : 'Class "oof" not found'],
|
||||
[['oof', 'bar'], \Error::class, \PHP_VERSION_ID < 80000 ? 'Class \'oof\' not found' : 'Class "oof" not found'],
|
||||
['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::staticsAction', \InvalidArgumentException::class, 'The controller for URI "/" is not callable: Expected method "staticsAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest", did you mean "staticAction"?'],
|
||||
['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::privateAction', \InvalidArgumentException::class, 'The controller for URI "/" is not callable: Method "privateAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest" should be public and non-abstract'],
|
||||
['Symfony\Component\HttpKernel\Tests\Controller\ControllerTest::protectedAction', \InvalidArgumentException::class, 'The controller for URI "/" is not callable: Method "protectedAction" on class "Symfony\Component\HttpKernel\Tests\Controller\ControllerTest" should be public and non-abstract'],
|
||||
|
@ -166,7 +166,11 @@ class EsmtpTransport extends SmtpTransport
|
||||
|
||||
return;
|
||||
} catch (TransportExceptionInterface $e) {
|
||||
$this->executeCommand("RSET\r\n", [250]);
|
||||
try {
|
||||
$this->executeCommand("RSET\r\n", [250]);
|
||||
} catch (TransportExceptionInterface $_) {
|
||||
// ignore this exception as it probably means that the server error was final
|
||||
}
|
||||
|
||||
// keep the error message, but tries the other authenticators
|
||||
$errors[$authenticator->getAuthKeyword()] = $e;
|
||||
|
@ -130,18 +130,6 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
|
||||
*/
|
||||
public function getTypes(string $class, string $property, array $context = []): ?array
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 70400) {
|
||||
try {
|
||||
$reflectionProperty = new \ReflectionProperty($class, $property);
|
||||
$type = $reflectionProperty->getType();
|
||||
if (null !== $type) {
|
||||
return $this->extractFromReflectionType($type, $reflectionProperty->getDeclaringClass());
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
if ($fromMutator = $this->extractFromMutator($class, $property)) {
|
||||
return $fromMutator;
|
||||
}
|
||||
@ -161,6 +149,18 @@ class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTyp
|
||||
return $fromDefaultValue;
|
||||
}
|
||||
|
||||
if (\PHP_VERSION_ID >= 70400) {
|
||||
try {
|
||||
$reflectionProperty = new \ReflectionProperty($class, $property);
|
||||
$type = $reflectionProperty->getType();
|
||||
if (null !== $type) {
|
||||
return $this->extractFromReflectionType($type, $reflectionProperty->getDeclaringClass());
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -414,6 +414,7 @@ class ReflectionExtractorTest extends TestCase
|
||||
{
|
||||
$this->assertEquals([new Type(Type::BUILTIN_TYPE_OBJECT, false, Dummy::class)], $this->extractor->getTypes(Php74Dummy::class, 'dummy'));
|
||||
$this->assertEquals([new Type(Type::BUILTIN_TYPE_BOOL, true)], $this->extractor->getTypes(Php74Dummy::class, 'nullableBoolProp'));
|
||||
$this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))], $this->extractor->getTypes(Php74Dummy::class, 'stringCollection'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,4 +18,14 @@ class Php74Dummy
|
||||
{
|
||||
public Dummy $dummy;
|
||||
private ?bool $nullableBoolProp;
|
||||
/** @var string[] */
|
||||
private array $stringCollection;
|
||||
|
||||
public function addStringCollection(string $string): void
|
||||
{
|
||||
}
|
||||
|
||||
public function removeStringCollection(string $string): void
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -1253,7 +1253,13 @@ class Parser
|
||||
for ($i = 1; isset($this->currentLine[$i]) && ']' !== $this->currentLine[$i]; ++$i) {
|
||||
}
|
||||
|
||||
$value .= trim($this->currentLine);
|
||||
$trimmedValue = trim($this->currentLine);
|
||||
|
||||
if ('' !== $trimmedValue && '#' === $trimmedValue[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value .= $trimmedValue;
|
||||
|
||||
if (isset($this->currentLine[$i]) && ']' === $this->currentLine[$i]) {
|
||||
break;
|
||||
|
@ -1897,6 +1897,30 @@ YAML
|
||||
[new TaggedValue('foo', 'bar')],
|
||||
'[ !foo bar ]',
|
||||
],
|
||||
'with-comments' => [
|
||||
[
|
||||
[new TaggedValue('foo', ['foo', 'baz'])],
|
||||
],
|
||||
<<<YAML
|
||||
- [!foo [
|
||||
foo,
|
||||
baz
|
||||
#bar
|
||||
]]
|
||||
YAML
|
||||
],
|
||||
'with-comments-trailing-comma' => [
|
||||
[
|
||||
[new TaggedValue('foo', ['foo', 'baz'])],
|
||||
],
|
||||
<<<YAML
|
||||
- [!foo [
|
||||
foo,
|
||||
baz,
|
||||
#bar
|
||||
]]
|
||||
YAML
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user