From 36ce9029f76d9720d0bc0ded179302e165c6b077 Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Fri, 2 Oct 2020 22:12:42 +0200 Subject: [PATCH 1/3] [Serializer][Minor] Fix exception message Wrong circular reference limit displayed. --- .../Normalizer/AbstractNormalizer.php | 2 +- .../Features/CircularReferenceTestTrait.php | 23 +++++++++++++++---- .../Normalizer/GetSetMethodNormalizerTest.php | 4 ++-- .../Tests/Normalizer/ObjectNormalizerTest.php | 4 ++-- .../Normalizer/PropertyNormalizerTest.php | 4 ++-- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 8830f13cf7..84d6db2e18 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -327,7 +327,7 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn return $circularReferenceHandler($object, $format, $context); } - throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d).', \get_class($object), $this->circularReferenceLimit)); + throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d).', \get_class($object), $context[self::CIRCULAR_REFERENCE_LIMIT] ?? $this->defaultContext[self::CIRCULAR_REFERENCE_LIMIT] ?? $this->circularReferenceLimit)); } /** diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/CircularReferenceTestTrait.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/CircularReferenceTestTrait.php index 1f51cc26a9..99eb10120d 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/CircularReferenceTestTrait.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/CircularReferenceTestTrait.php @@ -10,23 +10,36 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; */ trait CircularReferenceTestTrait { - abstract protected function getNormalizerForCircularReference(): NormalizerInterface; + abstract protected function getNormalizerForCircularReference(array $defaultContext): NormalizerInterface; abstract protected function getSelfReferencingModel(); - public function testUnableToNormalizeCircularReference() + public function provideUnableToNormalizeCircularReference(): array { - $normalizer = $this->getNormalizerForCircularReference(); + return [ + [[], [], 1], + [['circular_reference_limit' => 2], [], 2], + [['circular_reference_limit' => 2], ['circular_reference_limit' => 3], 3], + ]; + } + + /** + * @dataProvider provideUnableToNormalizeCircularReference + */ + public function testUnableToNormalizeCircularReference(array $defaultContext, array $context, int $expectedLimit) + { + $normalizer = $this->getNormalizerForCircularReference($defaultContext); $obj = $this->getSelfReferencingModel(); $this->expectException(CircularReferenceException::class); - $normalizer->normalize($obj, null, ['circular_reference_limit' => 2]); + $this->expectExceptionMessage(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d).', \get_class($obj), $expectedLimit)); + $normalizer->normalize($obj, null, $context); } public function testCircularReferenceHandler() { - $normalizer = $this->getNormalizerForCircularReference(); + $normalizer = $this->getNormalizerForCircularReference([]); $obj = $this->getSelfReferencingModel(); $expected = ['me' => \get_class($obj)]; diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php index 01925fe462..a3b4819656 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php @@ -247,10 +247,10 @@ class GetSetMethodNormalizerTest extends TestCase ); } - protected function getNormalizerForCircularReference(): GetSetMethodNormalizer + protected function getNormalizerForCircularReference(array $defaultContext): GetSetMethodNormalizer { $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())); - $normalizer = new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory)); + $normalizer = new GetSetMethodNormalizer($classMetadataFactory, new MetadataAwareNameConverter($classMetadataFactory), null, null, null, $defaultContext); new Serializer([$normalizer]); return $normalizer; diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php index 4c6ef1fadc..4a2ac344ec 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php @@ -365,9 +365,9 @@ class ObjectNormalizerTest extends TestCase // circular reference - protected function getNormalizerForCircularReference(): ObjectNormalizer + protected function getNormalizerForCircularReference(array $defaultContext): ObjectNormalizer { - $normalizer = new ObjectNormalizer(); + $normalizer = new ObjectNormalizer(null, null, null, null, null, null, $defaultContext); new Serializer([$normalizer]); return $normalizer; diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php index a111ec620e..8c7a0ead2c 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php @@ -191,9 +191,9 @@ class PropertyNormalizerTest extends TestCase $this->normalizer->setCallbacks($callbacks); } - protected function getNormalizerForCircularReference(): PropertyNormalizer + protected function getNormalizerForCircularReference(array $defaultContext): PropertyNormalizer { - $normalizer = new PropertyNormalizer(); + $normalizer = new PropertyNormalizer(null, null, null, null, null, $defaultContext); new Serializer([$normalizer]); return $normalizer; From 4ebbe3d86b8d67ca7d60d2b3c2897cacdaa178b0 Mon Sep 17 00:00:00 2001 From: Joni Halme Date: Tue, 31 Mar 2020 20:28:05 +0300 Subject: [PATCH 2/3] [Lock] Fix StoreFactory to accept same DSN syntax as AbstractAdapter --- src/Symfony/Component/Lock/Store/StoreFactory.php | 8 ++++---- .../Component/Lock/Tests/Store/StoreFactoryTest.php | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Lock/Store/StoreFactory.php b/src/Symfony/Component/Lock/Store/StoreFactory.php index b9a5c1e5ca..2e9172ff99 100644 --- a/src/Symfony/Component/Lock/Store/StoreFactory.php +++ b/src/Symfony/Component/Lock/Store/StoreFactory.php @@ -66,13 +66,13 @@ class StoreFactory case 'semaphore' === $connection: return new SemaphoreStore(); - case 0 === strpos($connection, 'redis://'): - case 0 === strpos($connection, 'rediss://'): - case 0 === strpos($connection, 'memcached://'): + case 0 === strpos($connection, 'redis:'): + case 0 === strpos($connection, 'rediss:'): + case 0 === strpos($connection, 'memcached:'): if (!class_exists(AbstractAdapter::class)) { throw new InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection)); } - $storeClass = 0 === strpos($connection, 'memcached://') ? MemcachedStore::class : RedisStore::class; + $storeClass = 0 === strpos($connection, 'memcached:') ? MemcachedStore::class : RedisStore::class; $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]); return new $storeClass($connection); diff --git a/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php b/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php index 1d88638d26..4e85cdc05f 100644 --- a/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php @@ -58,12 +58,14 @@ class StoreFactoryTest extends TestCase } if (class_exists(\Memcached::class) && class_exists(AbstractAdapter::class)) { yield ['memcached://server.com', MemcachedStore::class]; + yield ['memcached:?host[localhost]&host[localhost:12345]', MemcachedStore::class]; } - if (class_exists(\Redis::class) && class_exists(AbstractAdapter::class)) { + if ((class_exists(\Redis::class) || class_exists(\Predis\Client::class)) && class_exists(AbstractAdapter::class)) { yield ['redis://localhost', RedisStore::class]; yield ['redis://localhost?lazy=1', RedisStore::class]; yield ['redis://localhost?redis_cluster=1', RedisStore::class]; yield ['redis://localhost?redis_cluster=1&lazy=1', RedisStore::class]; + yield ['redis:?host[localhost]&host[localhost:6379]&redis_cluster=1', RedisStore::class]; } if (class_exists(\PDO::class)) { yield ['sqlite:/tmp/sqlite.db', PdoStore::class]; From 6a79f3e06fb9560ed3ec9f57983415a50e883887 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 3 Oct 2020 08:31:32 +0200 Subject: [PATCH 3/3] Fix tests --- src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php b/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php index 4e85cdc05f..06bdd57b6c 100644 --- a/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php +++ b/src/Symfony/Component/Lock/Tests/Store/StoreFactoryTest.php @@ -60,7 +60,7 @@ class StoreFactoryTest extends TestCase yield ['memcached://server.com', MemcachedStore::class]; yield ['memcached:?host[localhost]&host[localhost:12345]', MemcachedStore::class]; } - if ((class_exists(\Redis::class) || class_exists(\Predis\Client::class)) && class_exists(AbstractAdapter::class)) { + if (class_exists(\Redis::class) && class_exists(AbstractAdapter::class)) { yield ['redis://localhost', RedisStore::class]; yield ['redis://localhost?lazy=1', RedisStore::class]; yield ['redis://localhost?redis_cluster=1', RedisStore::class];