Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ade30f7

Browse files
committed
bug #47304 [Serializer] Fix caching context-aware encoders/decoders in ChainEncoder/ChainDecoder (Guite)
This PR was merged into the 4.4 branch. Discussion ---------- [Serializer] Fix caching context-aware encoders/decoders in ChainEncoder/ChainDecoder | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #38270 | License | MIT | Doc PR | - As proposed in #43231 (comment) Will require #47150 on 6.1 until a proper solution is implemented, hopefully in 6.2. Commits ------- 5902380 [Serializer] Fix caching context-aware encoders/decoders in ChainEncoder/ChainDecoder
2 parents f91c198 + 5902380 commit ade30f7

File tree

4 files changed

+52
-4
lines changed

4 files changed

+52
-4
lines changed

src/Symfony/Component/Serializer/Encoder/ChainDecoder.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,13 @@ private function getDecoder(string $format, array $context): DecoderInterface
6767
return $this->decoders[$this->decoderByFormat[$format]];
6868
}
6969

70+
$cache = true;
7071
foreach ($this->decoders as $i => $decoder) {
72+
$cache = $cache && !$decoder instanceof ContextAwareDecoderInterface;
7173
if ($decoder->supportsDecoding($format, $context)) {
72-
$this->decoderByFormat[$format] = $i;
74+
if ($cache) {
75+
$this->decoderByFormat[$format] = $i;
76+
}
7377

7478
return $decoder;
7579
}

src/Symfony/Component/Serializer/Encoder/ChainEncoder.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,13 @@ private function getEncoder(string $format, array $context): EncoderInterface
8585
return $this->encoders[$this->encoderByFormat[$format]];
8686
}
8787

88+
$cache = true;
8889
foreach ($this->encoders as $i => $encoder) {
90+
$cache = $cache && !$encoder instanceof ContextAwareEncoderInterface;
8991
if ($encoder->supportsEncoding($format, $context)) {
90-
$this->encoderByFormat[$format] = $i;
92+
if ($cache) {
93+
$this->encoderByFormat[$format] = $i;
94+
}
9195

9296
return $encoder;
9397
}

src/Symfony/Component/Serializer/Tests/Encoder/ChainDecoderTest.php

+21-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Serializer\Encoder\ChainDecoder;
16+
use Symfony\Component\Serializer\Encoder\ContextAwareDecoderInterface;
1617
use Symfony\Component\Serializer\Encoder\DecoderInterface;
1718
use Symfony\Component\Serializer\Exception\RuntimeException;
1819

@@ -28,14 +29,15 @@ class ChainDecoderTest extends TestCase
2829

2930
protected function setUp(): void
3031
{
31-
$this->decoder1 = $this->createMock(DecoderInterface::class);
32+
$this->decoder1 = $this->createMock(ContextAwareDecoderInterface::class);
3233
$this->decoder1
3334
->method('supportsDecoding')
3435
->willReturnMap([
3536
[self::FORMAT_1, [], true],
3637
[self::FORMAT_2, [], false],
3738
[self::FORMAT_3, [], false],
3839
[self::FORMAT_3, ['foo' => 'bar'], true],
40+
[self::FORMAT_3, ['foo' => 'bar2'], false],
3941
]);
4042

4143
$this->decoder2 = $this->createMock(DecoderInterface::class);
@@ -45,17 +47,35 @@ protected function setUp(): void
4547
[self::FORMAT_1, [], false],
4648
[self::FORMAT_2, [], true],
4749
[self::FORMAT_3, [], false],
50+
[self::FORMAT_3, ['foo' => 'bar'], false],
51+
[self::FORMAT_3, ['foo' => 'bar2'], true],
4852
]);
4953

5054
$this->chainDecoder = new ChainDecoder([$this->decoder1, $this->decoder2]);
5155
}
5256

5357
public function testSupportsDecoding()
5458
{
59+
$this->decoder1
60+
->method('decode')
61+
->willReturn('result1');
62+
$this->decoder2
63+
->method('decode')
64+
->willReturn('result2');
65+
5566
$this->assertTrue($this->chainDecoder->supportsDecoding(self::FORMAT_1));
67+
$this->assertEquals('result1', $this->chainDecoder->decode('', self::FORMAT_1, []));
68+
5669
$this->assertTrue($this->chainDecoder->supportsDecoding(self::FORMAT_2));
70+
$this->assertEquals('result2', $this->chainDecoder->decode('', self::FORMAT_2, []));
71+
5772
$this->assertFalse($this->chainDecoder->supportsDecoding(self::FORMAT_3));
73+
5874
$this->assertTrue($this->chainDecoder->supportsDecoding(self::FORMAT_3, ['foo' => 'bar']));
75+
$this->assertEquals('result1', $this->chainDecoder->decode('', self::FORMAT_3, ['foo' => 'bar']));
76+
77+
$this->assertTrue($this->chainDecoder->supportsDecoding(self::FORMAT_3, ['foo' => 'bar2']));
78+
$this->assertEquals('result2', $this->chainDecoder->decode('', self::FORMAT_3, ['foo' => 'bar2']));
5979
}
6080

6181
public function testDecode()

src/Symfony/Component/Serializer/Tests/Encoder/ChainEncoderTest.php

+21-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Serializer\Encoder\ChainEncoder;
16+
use Symfony\Component\Serializer\Encoder\ContextAwareEncoderInterface;
1617
use Symfony\Component\Serializer\Encoder\EncoderInterface;
1718
use Symfony\Component\Serializer\Encoder\NormalizationAwareInterface;
1819
use Symfony\Component\Serializer\Exception\RuntimeException;
@@ -29,14 +30,15 @@ class ChainEncoderTest extends TestCase
2930

3031
protected function setUp(): void
3132
{
32-
$this->encoder1 = $this->createMock(EncoderInterface::class);
33+
$this->encoder1 = $this->createMock(ContextAwareEncoderInterface::class);
3334
$this->encoder1
3435
->method('supportsEncoding')
3536
->willReturnMap([
3637
[self::FORMAT_1, [], true],
3738
[self::FORMAT_2, [], false],
3839
[self::FORMAT_3, [], false],
3940
[self::FORMAT_3, ['foo' => 'bar'], true],
41+
[self::FORMAT_3, ['foo' => 'bar2'], false],
4042
]);
4143

4244
$this->encoder2 = $this->createMock(EncoderInterface::class);
@@ -46,17 +48,35 @@ protected function setUp(): void
4648
[self::FORMAT_1, [], false],
4749
[self::FORMAT_2, [], true],
4850
[self::FORMAT_3, [], false],
51+
[self::FORMAT_3, ['foo' => 'bar'], false],
52+
[self::FORMAT_3, ['foo' => 'bar2'], true],
4953
]);
5054

5155
$this->chainEncoder = new ChainEncoder([$this->encoder1, $this->encoder2]);
5256
}
5357

5458
public function testSupportsEncoding()
5559
{
60+
$this->encoder1
61+
->method('encode')
62+
->willReturn('result1');
63+
$this->encoder2
64+
->method('encode')
65+
->willReturn('result2');
66+
5667
$this->assertTrue($this->chainEncoder->supportsEncoding(self::FORMAT_1));
68+
$this->assertEquals('result1', $this->chainEncoder->encode('', self::FORMAT_1, []));
69+
5770
$this->assertTrue($this->chainEncoder->supportsEncoding(self::FORMAT_2));
71+
$this->assertEquals('result2', $this->chainEncoder->encode('', self::FORMAT_2, []));
72+
5873
$this->assertFalse($this->chainEncoder->supportsEncoding(self::FORMAT_3));
74+
5975
$this->assertTrue($this->chainEncoder->supportsEncoding(self::FORMAT_3, ['foo' => 'bar']));
76+
$this->assertEquals('result1', $this->chainEncoder->encode('', self::FORMAT_3, ['foo' => 'bar']));
77+
78+
$this->assertTrue($this->chainEncoder->supportsEncoding(self::FORMAT_3, ['foo' => 'bar2']));
79+
$this->assertEquals('result2', $this->chainEncoder->encode('', self::FORMAT_3, ['foo' => 'bar2']));
6080
}
6181

6282
public function testEncode()

0 commit comments

Comments
 (0)