Merge branch '4.2'
* 4.2: [serializer] validate that the specified callbacks and max_depth_handler are actually callable [Serializer] Respect ignored attributes in cache key of normalizer fix resetting the COLUMN environment variable Fix TestRunner compatibility to PhpUnit 8 Fix dark themed componnents prevent mixup of the object to populate
This commit is contained in:
commit
9d3c86fdb6
@ -23,6 +23,24 @@ class CommandForV5 extends \PHPUnit_TextUI_Command
|
||||
*/
|
||||
protected function createRunner()
|
||||
{
|
||||
return new TestRunnerForV5($this->arguments['loader']);
|
||||
$listener = new SymfonyTestsListenerForV5();
|
||||
|
||||
$this->arguments['listeners'] = isset($this->arguments['listeners']) ? $this->arguments['listeners'] : array();
|
||||
|
||||
$registeredLocally = false;
|
||||
|
||||
foreach ($this->arguments['listeners'] as $registeredListener) {
|
||||
if ($registeredListener instanceof SymfonyTestsListenerForV5) {
|
||||
$registeredListener->globalListenerDisabled();
|
||||
$registeredLocally = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$registeredLocally) {
|
||||
$this->arguments['listeners'][] = $listener;
|
||||
}
|
||||
|
||||
return parent::createRunner();
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace Symfony\Bridge\PhpUnit\Legacy;
|
||||
|
||||
use PHPUnit\TextUI\Command as BaseCommand;
|
||||
use PHPUnit\TextUI\TestRunner as BaseRunner;
|
||||
use Symfony\Bridge\PhpUnit\TextUI\TestRunner;
|
||||
use Symfony\Bridge\PhpUnit\SymfonyTestsListener;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@ -27,6 +27,24 @@ class CommandForV6 extends BaseCommand
|
||||
*/
|
||||
protected function createRunner(): BaseRunner
|
||||
{
|
||||
return new TestRunner($this->arguments['loader']);
|
||||
$listener = new SymfonyTestsListener();
|
||||
|
||||
$this->arguments['listeners'] = isset($this->arguments['listeners']) ? $this->arguments['listeners'] : [];
|
||||
|
||||
$registeredLocally = false;
|
||||
|
||||
foreach ($this->arguments['listeners'] as $registeredListener) {
|
||||
if ($registeredListener instanceof SymfonyTestsListener) {
|
||||
$registeredListener->globalListenerDisabled();
|
||||
$registeredLocally = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$registeredLocally) {
|
||||
$this->arguments['listeners'][] = $listener;
|
||||
}
|
||||
|
||||
return parent::createRunner();
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
<?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\Bridge\PhpUnit\Legacy;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TestRunnerForV5 extends \PHPUnit_TextUI_TestRunner
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function handleConfiguration(array &$arguments)
|
||||
{
|
||||
$listener = new SymfonyTestsListenerForV5();
|
||||
|
||||
$result = parent::handleConfiguration($arguments);
|
||||
|
||||
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array();
|
||||
|
||||
$registeredLocally = false;
|
||||
|
||||
foreach ($arguments['listeners'] as $registeredListener) {
|
||||
if ($registeredListener instanceof SymfonyTestsListenerForV5) {
|
||||
$registeredListener->globalListenerDisabled();
|
||||
$registeredLocally = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$registeredLocally) {
|
||||
$arguments['listeners'][] = $listener;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
<?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\Bridge\PhpUnit\Legacy;
|
||||
|
||||
use PHPUnit\TextUI\TestRunner as BaseRunner;
|
||||
use Symfony\Bridge\PhpUnit\SymfonyTestsListener;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TestRunnerForV6 extends BaseRunner
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function handleConfiguration(array &$arguments)
|
||||
{
|
||||
$listener = new SymfonyTestsListener();
|
||||
|
||||
parent::handleConfiguration($arguments);
|
||||
|
||||
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array();
|
||||
|
||||
$registeredLocally = false;
|
||||
|
||||
foreach ($arguments['listeners'] as $registeredListener) {
|
||||
if ($registeredListener instanceof SymfonyTestsListener) {
|
||||
$registeredListener->globalListenerDisabled();
|
||||
$registeredLocally = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$registeredLocally) {
|
||||
$arguments['listeners'][] = $listener;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
<?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\Bridge\PhpUnit\Legacy;
|
||||
|
||||
use PHPUnit\TextUI\TestRunner as BaseRunner;
|
||||
use Symfony\Bridge\PhpUnit\SymfonyTestsListener;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TestRunnerForV7 extends BaseRunner
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function handleConfiguration(array &$arguments): void
|
||||
{
|
||||
$listener = new SymfonyTestsListener();
|
||||
|
||||
parent::handleConfiguration($arguments);
|
||||
|
||||
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array();
|
||||
|
||||
$registeredLocally = false;
|
||||
|
||||
foreach ($arguments['listeners'] as $registeredListener) {
|
||||
if ($registeredListener instanceof SymfonyTestsListener) {
|
||||
$registeredListener->globalListenerDisabled();
|
||||
$registeredLocally = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$registeredLocally) {
|
||||
$arguments['listeners'][] = $listener;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?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\Bridge\PhpUnit\TextUI;
|
||||
|
||||
if (class_exists('PHPUnit_Runner_Version') && version_compare(\PHPUnit_Runner_Version::id(), '6.0.0', '<')) {
|
||||
class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV5', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner');
|
||||
} elseif (version_compare(\PHPUnit\Runner\Version::id(), '7.0.0', '<')) {
|
||||
class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV6', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner');
|
||||
} else {
|
||||
class_alias('Symfony\Bridge\PhpUnit\Legacy\TestRunnerForV7', 'Symfony\Bridge\PhpUnit\TextUI\TestRunner');
|
||||
}
|
||||
|
||||
if (false) {
|
||||
class TestRunner
|
||||
{
|
||||
}
|
||||
}
|
@ -58,6 +58,7 @@
|
||||
|
||||
.message-item tbody.sf-toggle-content.sf-toggle-visible { display: table-row-group; }
|
||||
td.message-bus-dispatch-caller { background: #f1f2f3; }
|
||||
.theme-dark td.message-bus-dispatch-caller { background: var(--base-1); }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
|
@ -1011,6 +1011,8 @@ table.logs .metadata {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
}
|
||||
.theme-dark tr.status-error td,
|
||||
.theme-dark tr.status-warning td { border-bottom: unset; border-top: unset; }
|
||||
|
||||
{# Doctrine panel
|
||||
========================================================================= #}
|
||||
|
@ -48,6 +48,14 @@ class ApplicationTest extends TestCase
|
||||
$this->colSize = getenv('COLUMNS');
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS');
|
||||
putenv('SHELL_VERBOSITY');
|
||||
unset($_ENV['SHELL_VERBOSITY']);
|
||||
unset($_SERVER['SHELL_VERBOSITY']);
|
||||
}
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
self::$fixturesPath = realpath(__DIR__.'/Fixtures/');
|
||||
@ -1749,14 +1757,6 @@ class ApplicationTest extends TestCase
|
||||
$tester = new ApplicationTester($application);
|
||||
$tester->run(['command' => 'foo']);
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
putenv($this->colSize ? 'COLUMNS' : 'COLUMNS='.$this->colSize);
|
||||
putenv('SHELL_VERBOSITY');
|
||||
unset($_ENV['SHELL_VERBOSITY']);
|
||||
unset($_SERVER['SHELL_VERBOSITY']);
|
||||
}
|
||||
}
|
||||
|
||||
class CustomApplication extends Application
|
||||
|
@ -33,7 +33,7 @@ class ProgressBarTest extends TestCase
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
putenv($this->colSize ? 'COLUMNS' : 'COLUMNS='.$this->colSize);
|
||||
putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS');
|
||||
}
|
||||
|
||||
public function testMultipleStart()
|
||||
|
@ -38,7 +38,7 @@ class SymfonyStyleTest extends TestCase
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
putenv($this->colSize ? 'COLUMNS' : 'COLUMNS='.$this->colSize);
|
||||
putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS');
|
||||
$this->command = null;
|
||||
$this->tester = null;
|
||||
}
|
||||
|
@ -25,6 +25,12 @@ class TerminalTest extends TestCase
|
||||
$this->lineSize = getenv('LINES');
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
putenv($this->colSize ? 'COLUMNS='.$this->colSize : 'COLUMNS');
|
||||
putenv($this->lineSize ? 'LINES' : 'LINES='.$this->lineSize);
|
||||
}
|
||||
|
||||
public function test()
|
||||
{
|
||||
putenv('COLUMNS=100');
|
||||
@ -40,12 +46,6 @@ class TerminalTest extends TestCase
|
||||
$this->assertSame(60, $terminal->getHeight());
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
putenv($this->colSize ? 'COLUMNS' : 'COLUMNS='.$this->colSize);
|
||||
putenv($this->lineSize ? 'LINES' : 'LINES='.$this->lineSize);
|
||||
}
|
||||
|
||||
public function test_zero_values()
|
||||
{
|
||||
putenv('COLUMNS=0');
|
||||
|
@ -99,10 +99,14 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
|
||||
$this->nameConverter = $nameConverter;
|
||||
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
|
||||
|
||||
if (\is_array($this->defaultContext[self::CALLBACKS] ?? null)) {
|
||||
if (isset($this->defaultContext[self::CALLBACKS])) {
|
||||
if (!\is_array($this->defaultContext[self::CALLBACKS])) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" default context option must be an array of callables.', self::CALLBACKS));
|
||||
}
|
||||
|
||||
foreach ($this->defaultContext[self::CALLBACKS] as $attribute => $callback) {
|
||||
if (!\is_callable($callback)) {
|
||||
throw new InvalidArgumentException(sprintf('The given callback for attribute "%s" is not callable.', $attribute));
|
||||
throw new InvalidArgumentException(sprintf('Invalid callback found for attribute "%s" in the "%s" default context option.', $attribute, self::CALLBACKS));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -385,6 +389,8 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
|
||||
|
||||
return $object;
|
||||
}
|
||||
// clean up even if no match
|
||||
unset($context[static::OBJECT_TO_POPULATE]);
|
||||
|
||||
$constructor = $this->getConstructor($data, $class, $context, $reflectionClass, $allowedAttributes);
|
||||
if ($constructor) {
|
||||
@ -453,7 +459,7 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
|
||||
throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $parameter->getClass(), self::class));
|
||||
}
|
||||
$parameterClass = $parameter->getClass()->getName();
|
||||
$parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $parameterName));
|
||||
$parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $parameterName, $format));
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $parameterName), 0, $e);
|
||||
@ -468,14 +474,15 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parentContext
|
||||
* @param string $attribute
|
||||
* @param array $parentContext
|
||||
* @param string $attribute Attribute name
|
||||
* @param string|null $format
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
protected function createChildContext(array $parentContext, $attribute)
|
||||
protected function createChildContext(array $parentContext, $attribute/*, string $format = null */)
|
||||
{
|
||||
if (isset($parentContext[self::ATTRIBUTES][$attribute])) {
|
||||
$parentContext[self::ATTRIBUTES] = $parentContext[self::ATTRIBUTES][$attribute];
|
||||
|
@ -61,6 +61,11 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
||||
public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, callable $objectClassResolver = null, array $defaultContext = [])
|
||||
{
|
||||
parent::__construct($classMetadataFactory, $nameConverter, $defaultContext);
|
||||
|
||||
if (isset($this->defaultContext[self::MAX_DEPTH_HANDLER]) && !\is_callable($this->defaultContext[self::MAX_DEPTH_HANDLER])) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" given in the default context is not callable.', self::MAX_DEPTH_HANDLER));
|
||||
}
|
||||
|
||||
$this->defaultContext[self::EXCLUDE_FROM_CACHE_KEY] = [self::CIRCULAR_REFERENCE_LIMIT_COUNTERS];
|
||||
|
||||
$this->propertyTypeExtractor = $propertyTypeExtractor;
|
||||
@ -89,6 +94,18 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
||||
$context['cache_key'] = $this->getCacheKey($format, $context);
|
||||
}
|
||||
|
||||
if (isset($context[self::CALLBACKS])) {
|
||||
if (!\is_array($context[self::CALLBACKS])) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" context option must be an array of callables.', self::CALLBACKS));
|
||||
}
|
||||
|
||||
foreach ($context[self::CALLBACKS] as $attribute => $callback) {
|
||||
if (!\is_callable($callback)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid callback found for attribute "%s" in the "%s" context option.', $attribute, self::CALLBACKS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->isCircularReference($object, $context)) {
|
||||
return $this->handleCircularReference($object, $format, $context);
|
||||
}
|
||||
@ -98,7 +115,15 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
||||
$attributes = $this->getAttributes($object, $format, $context);
|
||||
$class = $this->objectClassResolver ? ($this->objectClassResolver)($object) : \get_class($object);
|
||||
$attributesMetadata = $this->classMetadataFactory ? $this->classMetadataFactory->getMetadataFor($class)->getAttributesMetadata() : null;
|
||||
$maxDepthHandler = $context[self::MAX_DEPTH_HANDLER] ?? $this->defaultContext[self::MAX_DEPTH_HANDLER] ?? $this->maxDepthHandler;
|
||||
if (isset($context[self::MAX_DEPTH_HANDLER])) {
|
||||
$maxDepthHandler = $context[self::MAX_DEPTH_HANDLER];
|
||||
if (!\is_callable($maxDepthHandler)) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" given in the context is not callable.', self::MAX_DEPTH_HANDLER));
|
||||
}
|
||||
} else {
|
||||
// already validated in constructor resp by type declaration of setMaxDepthHandler
|
||||
$maxDepthHandler = $this->defaultContext[self::MAX_DEPTH_HANDLER] ?? $this->maxDepthHandler;
|
||||
}
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
$maxDepthReached = false;
|
||||
@ -131,7 +156,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
||||
throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute));
|
||||
}
|
||||
|
||||
$data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute)), $class, $format, $context);
|
||||
$data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute, $format)), $class, $format, $context);
|
||||
}
|
||||
|
||||
return $data;
|
||||
@ -187,21 +212,17 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
||||
return $allowedAttributes;
|
||||
}
|
||||
|
||||
if ($context[self::ATTRIBUTES] ?? $this->defaultContext[self::ATTRIBUTES] ?? false) {
|
||||
return $this->extractAttributes($object, $format, $context);
|
||||
}
|
||||
|
||||
if (isset($this->attributesCache[$class])) {
|
||||
return $this->attributesCache[$class];
|
||||
}
|
||||
|
||||
$attributes = $this->extractAttributes($object, $format, $context);
|
||||
|
||||
if ($this->classDiscriminatorResolver && $mapping = $this->classDiscriminatorResolver->getMappingForMappedObject($object)) {
|
||||
array_unshift($attributes, $mapping->getTypeProperty());
|
||||
}
|
||||
|
||||
return $this->attributesCache[$class] = $attributes;
|
||||
if ($context['cache_key']) {
|
||||
$this->attributesCache[$key] = $attributes;
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -356,7 +377,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
||||
throw new LogicException(sprintf('Cannot denormalize attribute "%s" for class "%s" because injected serializer is not a denormalizer', $attribute, $class));
|
||||
}
|
||||
|
||||
$childContext = $this->createChildContext($context, $attribute);
|
||||
$childContext = $this->createChildContext($context, $attribute, $format);
|
||||
if ($this->serializer->supportsDenormalization($data, $class, $format, $childContext)) {
|
||||
return $this->serializer->denormalize($data, $class, $format, $childContext);
|
||||
}
|
||||
@ -486,7 +507,32 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cache key to use.
|
||||
* Overwritten to update the cache key for the child.
|
||||
*
|
||||
* We must not mix up the attribute cache between parent and children.
|
||||
*
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createChildContext(array $parentContext, $attribute/*, string $format = null */)
|
||||
{
|
||||
if (\func_num_args() >= 3) {
|
||||
$format = \func_get_arg(2);
|
||||
} else {
|
||||
// will be deprecated in version 4
|
||||
$format = null;
|
||||
}
|
||||
|
||||
$context = parent::createChildContext($parentContext, $attribute, $format);
|
||||
// format is already included in the cache_key of the parent.
|
||||
$context['cache_key'] = $this->getCacheKey($format, $context);
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the cache key for the attributes cache.
|
||||
*
|
||||
* The key must be different for every option in the context that could change which attributes should be handled.
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
@ -496,9 +542,14 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
|
||||
unset($context[$key]);
|
||||
}
|
||||
unset($context[self::EXCLUDE_FROM_CACHE_KEY]);
|
||||
unset($context['cache_key']); // avoid artificially different keys
|
||||
|
||||
try {
|
||||
return md5($format.serialize($context));
|
||||
return md5($format.serialize([
|
||||
'context' => $context,
|
||||
'ignored' => $this->ignoredAttributes,
|
||||
'camelized' => $this->camelizedAttributes,
|
||||
]));
|
||||
} catch (\Exception $exception) {
|
||||
// The context cannot be serialized, skip the cache
|
||||
return false;
|
||||
|
@ -394,6 +394,30 @@ class ObjectNormalizerTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testObjectToPopulateNoMatch()
|
||||
{
|
||||
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
|
||||
$this->normalizer = new ObjectNormalizer($classMetadataFactory, null, null, new PhpDocExtractor());
|
||||
new Serializer([$this->normalizer]);
|
||||
|
||||
$objectToPopulate = new ObjectInner();
|
||||
$objectToPopulate->foo = 'foo';
|
||||
|
||||
$outer = $this->normalizer->denormalize([
|
||||
'foo' => 'foo',
|
||||
'inner' => [
|
||||
'bar' => 'bar',
|
||||
],
|
||||
], ObjectOuter::class, null, [ObjectNormalizer::OBJECT_TO_POPULATE => $objectToPopulate]);
|
||||
|
||||
$this->assertInstanceOf(ObjectOuter::class, $outer);
|
||||
$inner = $outer->getInner();
|
||||
$this->assertInstanceOf(ObjectInner::class, $inner);
|
||||
$this->assertNotSame($objectToPopulate, $inner);
|
||||
$this->assertSame('bar', $inner->bar);
|
||||
$this->assertNull($inner->foo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideCallbacks
|
||||
*/
|
||||
@ -472,6 +496,16 @@ class ObjectNormalizerTest extends TestCase
|
||||
['fooBar' => 'foobar'],
|
||||
$this->normalizer->normalize($obj, 'any')
|
||||
);
|
||||
|
||||
$this->normalizer->setIgnoredAttributes(['foo', 'baz', 'camelCase', 'object']);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
'fooBar' => 'foobar',
|
||||
'bar' => 'bar',
|
||||
],
|
||||
$this->normalizer->normalize($obj, 'any')
|
||||
);
|
||||
}
|
||||
|
||||
public function testIgnoredAttributesDenormalize()
|
||||
@ -781,7 +815,11 @@ class ObjectNormalizerTest extends TestCase
|
||||
$this->normalizer->setMaxDepthHandler($handler);
|
||||
}
|
||||
} else {
|
||||
$this->createNormalizer([ObjectNormalizer::MAX_DEPTH_HANDLER => $handler], $classMetadataFactory);
|
||||
$context = [];
|
||||
if (null !== $handler) {
|
||||
$context[ObjectNormalizer::MAX_DEPTH_HANDLER] = $handler;
|
||||
}
|
||||
$this->createNormalizer($context, $classMetadataFactory);
|
||||
}
|
||||
$this->serializer = new Serializer([$this->normalizer]);
|
||||
$this->normalizer->setSerializer($this->serializer);
|
||||
@ -1208,6 +1246,9 @@ class ObjectOuter
|
||||
{
|
||||
public $foo;
|
||||
public $bar;
|
||||
/**
|
||||
* @var ObjectInner
|
||||
*/
|
||||
private $inner;
|
||||
private $date;
|
||||
|
||||
|
Reference in New Issue
Block a user