Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b7795cc

Browse filesBrowse files
Merge branch '6.4' into 7.1
* 6.4: [DoctrineBridge] Fix Connection::createSchemaManager() for Doctrine DBAL v2 [HttpClient] Various cleanups after recent changes do not add child nodes to EmptyNode instances consider write property visibility to decide whether a property is writable add comment explaining why HttpClient tests are run separately silence warnings issued by Redis Sentinel on connection issues
2 parents 7b20ed0 + 76df983 commit b7795cc
Copy full SHA for b7795cc

File tree

Expand file treeCollapse file tree

17 files changed

+104
-84
lines changed
Filter options
Expand file treeCollapse file tree

17 files changed

+104
-84
lines changed

‎.github/workflows/windows.yml

Copy file name to clipboardExpand all lines: .github/workflows/windows.yml
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ jobs:
111111
Remove-Item -Path src\Symfony\Bridge\PhpUnit -Recurse
112112
mv src\Symfony\Component\HttpClient\phpunit.xml.dist src\Symfony\Component\HttpClient\phpunit.xml
113113
php phpunit src\Symfony --exclude-group tty,benchmark,intl-data,network,transient-on-windows || ($x = 1)
114+
# HttpClient tests need to run separately, they block when run with other components' tests concurrently
114115
php phpunit src\Symfony\Component\HttpClient || ($x = 1)
115116
116117
exit $x
@@ -124,6 +125,7 @@ jobs:
124125
125126
Copy c:\php\php.ini-max c:\php\php.ini
126127
php phpunit src\Symfony --exclude-group tty,benchmark,intl-data,network,transient-on-windows || ($x = 1)
128+
# HttpClient tests need to run separately, they block when run with other components' tests concurrently
127129
php phpunit src\Symfony\Component\HttpClient || ($x = 1)
128130
129131
exit $x

‎src/Symfony/Bridge/Doctrine/SchemaListener/AbstractSchemaListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Doctrine/SchemaListener/AbstractSchemaListener.php
+1-2Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ abstract public function postGenerateSchema(GenerateSchemaEventArgs $event): voi
2424
protected function getIsSameDatabaseChecker(Connection $connection): \Closure
2525
{
2626
return static function (\Closure $exec) use ($connection): bool {
27-
$schemaManager = $connection->createSchemaManager();
28-
27+
$schemaManager = method_exists($connection, 'createSchemaManager') ? $connection->createSchemaManager() : $connection->getSchemaManager();
2928
$checkTable = 'schema_subscriber_check_'.bin2hex(random_bytes(7));
3029
$table = new Table($checkTable);
3130
$table->addColumn('id', Types::INTEGER)

‎src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Bridge\Twig\Node\TransNode;
1616
use Twig\Environment;
1717
use Twig\Node\BlockNode;
18+
use Twig\Node\EmptyNode;
1819
use Twig\Node\Expression\ArrayExpression;
1920
use Twig\Node\Expression\AssignNameExpression;
2021
use Twig\Node\Expression\ConstantExpression;
@@ -70,6 +71,12 @@ public function enterNode(Node $node, Environment $env): Node
7071

7172
if ($node instanceof FilterExpression && 'trans' === ($node->hasAttribute('twig_callable') ? $node->getAttribute('twig_callable')->getName() : $node->getNode('filter')->getAttribute('value'))) {
7273
$arguments = $node->getNode('arguments');
74+
75+
if ($arguments instanceof EmptyNode) {
76+
$arguments = new Nodes();
77+
$node->setNode('arguments', $arguments);
78+
}
79+
7380
if ($this->isNamedArguments($arguments)) {
7481
if (!$arguments->hasNode('domain') && !$arguments->hasNode(1)) {
7582
$arguments->setNode('domain', $this->scope->get('domain'));

‎src/Symfony/Component/HttpClient/CurlHttpClient.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/CurlHttpClient.php
+2-5Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,8 @@ private static function createRedirectResolver(array $options, string $host, int
417417
}
418418
}
419419

420-
return static function ($ch, string $location, bool $noContent, bool &$locationHasHost) use (&$redirectHeaders, $options) {
420+
return static function ($ch, string $location, bool $noContent) use (&$redirectHeaders, $options) {
421421
try {
422-
$locationHasHost = false;
423422
$location = self::parseUrl($location);
424423
$url = self::parseUrl(curl_getinfo($ch, \CURLINFO_EFFECTIVE_URL));
425424
$url = self::resolveUrl($location, $url);
@@ -433,9 +432,7 @@ private static function createRedirectResolver(array $options, string $host, int
433432
$redirectHeaders['with_auth'] = array_filter($redirectHeaders['with_auth'], $filterContentHeaders);
434433
}
435434

436-
$locationHasHost = isset($location['authority']);
437-
438-
if ($redirectHeaders && $locationHasHost) {
435+
if ($redirectHeaders && isset($location['authority'])) {
439436
$port = parse_url($location['authority'], \PHP_URL_PORT) ?: ('http:' === $location['scheme'] ? 80 : 443);
440437
$requestHeaders = parse_url($location['authority'], \PHP_URL_HOST) === $redirectHeaders['host'] && $redirectHeaders['port'] === $port ? $redirectHeaders['with_auth'] : $redirectHeaders['no_auth'];
441438
curl_setopt($ch, \CURLOPT_HTTPHEADER, $requestHeaders);

‎src/Symfony/Component/HttpClient/NativeHttpClient.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/NativeHttpClient.php
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ public function request(string $method, string $url, array $options = []): Respo
155155

156156
$progressInfo = $info;
157157
$progressInfo['url'] = implode('', $info['url']);
158+
$progressInfo['resolve'] = $resolve;
158159
unset($progressInfo['size_body']);
159160

160161
// Memoize the last progress to ease calling the callback periodically when no network transfer happens
@@ -167,7 +168,7 @@ public function request(string $method, string $url, array $options = []): Respo
167168
$lastProgress = $progress ?: $lastProgress;
168169
}
169170

170-
$onProgress($lastProgress[0], $lastProgress[1], $progressInfo, $resolve);
171+
$onProgress($lastProgress[0], $lastProgress[1], $progressInfo);
171172
};
172173
} elseif (0 < $options['max_duration']) {
173174
$maxDuration = $options['max_duration'];
@@ -352,6 +353,7 @@ private static function dnsResolve(string $host, NativeClientState $multi, array
352353

353354
$multi->dnsCache[$host] = $ip = $ip[0];
354355
$info['debug'] .= "* Added {$host}:0:{$ip} to DNS cache\n";
356+
$host = $ip;
355357
} else {
356358
$info['debug'] .= "* Hostname was found in DNS cache\n";
357359
$host = str_contains($ip, ':') ? "[$ip]" : $ip;

‎src/Symfony/Component/HttpClient/NoPrivateNetworkHttpClient.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/NoPrivateNetworkHttpClient.php
+8-12Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,20 @@ public function request(string $method, string $url, array $options = []): Respo
5656

5757
$subnets = $this->subnets;
5858

59-
$options['on_progress'] = static function (int $dlNow, int $dlSize, array $info, ?\Closure $resolve = null) use ($onProgress, $subnets): void {
59+
$options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use ($onProgress, $subnets): void {
6060
static $lastUrl = '';
6161
static $lastPrimaryIp = '';
6262

6363
if ($info['url'] !== $lastUrl) {
64-
$host = trim(parse_url($info['url'], PHP_URL_HOST) ?: '', '[]');
65-
$resolve ??= static fn () => null;
64+
$host = parse_url($info['url'], PHP_URL_HOST) ?: '';
65+
$resolve = $info['resolve'] ?? static function () { return null; };
6666

67-
if (($ip = $host)
68-
&& !filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)
69-
&& !filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)
70-
&& !$ip = $resolve($host)
67+
if (($ip = trim($host, '[]'))
68+
&& !filter_var($ip, \FILTER_VALIDATE_IP)
69+
&& !($ip = $resolve($host))
70+
&& $ip = @(gethostbynamel($host)[0] ?? dns_get_record($host, \DNS_AAAA)[0]['ipv6'] ?? null)
7171
) {
72-
if ($ip = @(dns_get_record($host, \DNS_A)[0]['ip'] ?? null)) {
73-
$resolve($host, $ip);
74-
} elseif ($ip = @(dns_get_record($host, \DNS_AAAA)[0]['ipv6'] ?? null)) {
75-
$resolve($host, '['.$ip.']');
76-
}
72+
$resolve($host, $ip);
7773
}
7874

7975
if ($ip && IpUtils::checkIp($ip, $subnets ?? IpUtils::PRIVATE_SUBNETS)) {

‎src/Symfony/Component/HttpClient/Response/AmpResponse.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/Response/AmpResponse.php
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ public function __construct(
100100
$onProgress = $options['on_progress'] ?? static function () {};
101101
$onProgress = $this->onProgress = static function () use (&$info, $onProgress, $resolve) {
102102
$info['total_time'] = microtime(true) - $info['start_time'];
103-
$onProgress((int) $info['size_download'], ((int) (1 + $info['download_content_length']) ?: 1) - 1, (array) $info, $resolve);
103+
$info['resolve'] = $resolve;
104+
$onProgress((int) $info['size_download'], ((int) (1 + $info['download_content_length']) ?: 1) - 1, (array) $info);
104105
};
105106

106107
$pauseDeferred = new Deferred();

‎src/Symfony/Component/HttpClient/Response/AsyncContext.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/Response/AsyncContext.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ public function replaceRequest(string $method, string $url, array $options = [])
161161
$this->info['previous_info'][] = $info = $this->response->getInfo();
162162
if (null !== $onProgress = $options['on_progress'] ?? null) {
163163
$thisInfo = &$this->info;
164-
$options['on_progress'] = static function (int $dlNow, int $dlSize, array $info, ?\Closure $resolve = null) use (&$thisInfo, $onProgress) {
165-
$onProgress($dlNow, $dlSize, $thisInfo + $info, $resolve);
164+
$options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use (&$thisInfo, $onProgress) {
165+
$onProgress($dlNow, $dlSize, $thisInfo + $info);
166166
};
167167
}
168168
if (0 < ($info['max_duration'] ?? 0) && 0 < ($info['total_time'] ?? 0)) {

‎src/Symfony/Component/HttpClient/Response/AsyncResponse.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/Response/AsyncResponse.php
+16-3Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public function __construct(HttpClientInterface $client, string $method, string
5252

5353
if (null !== $onProgress = $options['on_progress'] ?? null) {
5454
$thisInfo = &$this->info;
55-
$options['on_progress'] = static function (int $dlNow, int $dlSize, array $info, ?\Closure $resolve = null) use (&$thisInfo, $onProgress) {
56-
$onProgress($dlNow, $dlSize, $thisInfo + $info, $resolve);
55+
$options['on_progress'] = static function (int $dlNow, int $dlSize, array $info) use (&$thisInfo, $onProgress) {
56+
$onProgress($dlNow, $dlSize, $thisInfo + $info);
5757
};
5858
}
5959
$this->response = $client->request($method, $url, ['buffer' => false] + $options);
@@ -118,11 +118,20 @@ public function getHeaders(bool $throw = true): array
118118

119119
public function getInfo(?string $type = null): mixed
120120
{
121+
if ('debug' === ($type ?? 'debug')) {
122+
$debug = implode('', array_column($this->info['previous_info'] ?? [], 'debug'));
123+
$debug .= $this->response->getInfo('debug');
124+
125+
if ('debug' === $type) {
126+
return $debug;
127+
}
128+
}
129+
121130
if (null !== $type) {
122131
return $this->info[$type] ?? $this->response->getInfo($type);
123132
}
124133

125-
return $this->info + $this->response->getInfo();
134+
return array_merge($this->info + $this->response->getInfo(), ['debug' => $debug]);
126135
}
127136

128137
/**
@@ -253,6 +262,7 @@ public static function stream(iterable $responses, ?float $timeout = null, ?stri
253262
return;
254263
}
255264

265+
$chunk = null;
256266
foreach ($client->stream($wrappedResponses, $timeout) as $response => $chunk) {
257267
$r = $asyncMap[$response];
258268

@@ -295,6 +305,9 @@ public static function stream(iterable $responses, ?float $timeout = null, ?stri
295305
}
296306
}
297307

308+
if (null === $chunk) {
309+
throw new \LogicException(\sprintf('"%s" is not compliant with HttpClientInterface: its "stream()" method didn\'t yield any chunks when it should have.', get_debug_type($client)));
310+
}
298311
if (null === $chunk->getError() && $chunk->isLast()) {
299312
$r->yieldedState = self::LAST_CHUNK_YIELDED;
300313
}

‎src/Symfony/Component/HttpClient/Response/CurlResponse.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/Response/CurlResponse.php
+2-12Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public function __construct(
135135
try {
136136
rewind($debugBuffer);
137137
$debug = ['debug' => stream_get_contents($debugBuffer)];
138-
$onProgress($dlNow, $dlSize, $url + curl_getinfo($ch) + $info + $debug, $resolve);
138+
$onProgress($dlNow, $dlSize, $url + curl_getinfo($ch) + $info + $debug + ['resolve' => $resolve]);
139139
} catch (\Throwable $e) {
140140
$multi->handlesActivity[(int) $ch][] = null;
141141
$multi->handlesActivity[(int) $ch][] = $e;
@@ -425,21 +425,11 @@ private static function parseHeaderLine($ch, string $data, array &$info, array &
425425
$info['http_method'] = 'HEAD' === $info['http_method'] ? 'HEAD' : 'GET';
426426
curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, $info['http_method']);
427427
}
428-
$locationHasHost = false;
429428

430-
if (null === $info['redirect_url'] = $resolveRedirect($ch, $location, $noContent, $locationHasHost)) {
429+
if (null === $info['redirect_url'] = $resolveRedirect($ch, $location, $noContent)) {
431430
$options['max_redirects'] = curl_getinfo($ch, \CURLINFO_REDIRECT_COUNT);
432431
curl_setopt($ch, \CURLOPT_FOLLOWLOCATION, false);
433432
curl_setopt($ch, \CURLOPT_MAXREDIRS, $options['max_redirects']);
434-
} elseif ($locationHasHost) {
435-
$url = parse_url($info['redirect_url']);
436-
437-
if (null !== $ip = $multi->dnsCache->hostnames[$url['host'] = strtolower($url['host'])] ?? null) {
438-
// Populate DNS cache for redirects if needed
439-
$port = $url['port'] ?? ('http' === $url['scheme'] ? 80 : 443);
440-
curl_setopt($ch, \CURLOPT_RESOLVE, ["{$url['host']}:$port:$ip"]);
441-
$multi->dnsCache->removals["-{$url['host']}:$port"] = "-{$url['host']}:$port";
442-
}
443433
}
444434
}
445435

‎src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/Tests/NoPrivateNetworkHttpClientTest.php
+16-38Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public function testExcludeByIp(string $ipAddr, $subnets, bool $mustThrow)
7575
$this->expectExceptionMessage(sprintf('IP "%s" is blocked for "%s".', $ipAddr, $url));
7676
}
7777

78-
$previousHttpClient = $this->getHttpClientMock($url, $ipAddr, $content);
78+
$previousHttpClient = $this->getMockHttpClient($ipAddr, $content);
7979
$client = new NoPrivateNetworkHttpClient($previousHttpClient, $subnets);
8080
$response = $client->request('GET', $url);
8181

@@ -91,14 +91,15 @@ public function testExcludeByIp(string $ipAddr, $subnets, bool $mustThrow)
9191
public function testExcludeByHost(string $ipAddr, $subnets, bool $mustThrow)
9292
{
9393
$content = 'foo';
94-
$url = sprintf('http://%s/', str_contains($ipAddr, ':') ? sprintf('[%s]', $ipAddr) : $ipAddr);
94+
$host = str_contains($ipAddr, ':') ? sprintf('[%s]', $ipAddr) : $ipAddr;
95+
$url = sprintf('http://%s/', $host);
9596

9697
if ($mustThrow) {
9798
$this->expectException(TransportException::class);
98-
$this->expectExceptionMessage(sprintf('Host "%s" is blocked for "%s".', $ipAddr, $url));
99+
$this->expectExceptionMessage(sprintf('Host "%s" is blocked for "%s".', $host, $url));
99100
}
100101

101-
$previousHttpClient = $this->getHttpClientMock($url, $ipAddr, $content);
102+
$previousHttpClient = $this->getMockHttpClient($ipAddr, $content);
102103
$client = new NoPrivateNetworkHttpClient($previousHttpClient, $subnets);
103104
$response = $client->request('GET', $url);
104105

@@ -119,7 +120,7 @@ public function testCustomOnProgressCallback()
119120
++$executionCount;
120121
};
121122

122-
$previousHttpClient = $this->getHttpClientMock($url, $ipAddr, $content);
123+
$previousHttpClient = $this->getMockHttpClient($ipAddr, $content);
123124
$client = new NoPrivateNetworkHttpClient($previousHttpClient);
124125
$response = $client->request('GET', $url, ['on_progress' => $customCallback]);
125126

@@ -132,7 +133,6 @@ public function testNonCallableOnProgressCallback()
132133
{
133134
$ipAddr = '104.26.14.6';
134135
$url = sprintf('http://%s/', $ipAddr);
135-
$content = 'bar';
136136
$customCallback = sprintf('cb_%s', microtime(true));
137137

138138
$this->expectException(InvalidArgumentException::class);
@@ -142,38 +142,16 @@ public function testNonCallableOnProgressCallback()
142142
$client->request('GET', $url, ['on_progress' => $customCallback]);
143143
}
144144

145-
private function getHttpClientMock(string $url, string $ipAddr, string $content)
145+
public function testConstructor()
146146
{
147-
$previousHttpClient = $this
148-
->getMockBuilder(HttpClientInterface::class)
149-
->getMock();
150-
151-
$previousHttpClient
152-
->expects($this->once())
153-
->method('request')
154-
->with(
155-
'GET',
156-
$url,
157-
$this->callback(function ($options) {
158-
$this->assertArrayHasKey('on_progress', $options);
159-
$onProgress = $options['on_progress'];
160-
$this->assertIsCallable($onProgress);
161-
162-
return true;
163-
})
164-
)
165-
->willReturnCallback(function ($method, $url, $options) use ($ipAddr, $content): ResponseInterface {
166-
$info = [
167-
'primary_ip' => $ipAddr,
168-
'url' => $url,
169-
];
170-
171-
$onProgress = $options['on_progress'];
172-
$onProgress(0, 0, $info);
173-
174-
return MockResponse::fromRequest($method, $url, [], new MockResponse($content));
175-
});
176-
177-
return $previousHttpClient;
147+
$this->expectException(\TypeError::class);
148+
$this->expectExceptionMessage('Argument 2 passed to "Symfony\Component\HttpClient\NoPrivateNetworkHttpClient::__construct()" must be of the type array, string or null. "int" given.');
149+
150+
new NoPrivateNetworkHttpClient(new MockHttpClient(), 3);
151+
}
152+
153+
private function getMockHttpClient(string $ipAddr, string $content)
154+
{
155+
return new MockHttpClient(new MockResponse($content, ['primary_ip' => $ipAddr]));
178156
}
179157
}

‎src/Symfony/Component/HttpClient/TraceableHttpClient.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpClient/TraceableHttpClient.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ public function request(string $method, string $url, array $options = []): Respo
5555
$content = false;
5656
}
5757

58-
$options['on_progress'] = function (int $dlNow, int $dlSize, array $info, ?\Closure $resolve = null) use (&$traceInfo, $onProgress) {
58+
$options['on_progress'] = function (int $dlNow, int $dlSize, array $info) use (&$traceInfo, $onProgress) {
5959
$traceInfo = $info;
6060

6161
if (null !== $onProgress) {
62-
$onProgress($dlNow, $dlSize, $info, $resolve);
62+
$onProgress($dlNow, $dlSize, $info);
6363
}
6464
};
6565

‎src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public function __construct(array $options, \Redis|Relay|\RedisCluster|null $red
140140
'readTimeout' => $options['read_timeout'],
141141
];
142142

143-
$sentinel = new \RedisSentinel($params);
143+
$sentinel = @new \RedisSentinel($params);
144144
} else {
145145
$sentinel = @new $sentinelClass($host, $port, $options['timeout'], $options['persistent_id'], $options['retry_interval'], $options['read_timeout']);
146146
}

‎src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,10 @@ private function isAllowedProperty(string $class, string $property, bool $writeA
704704
return false;
705705
}
706706

707+
if (\PHP_VERSION_ID >= 80400 && $writeAccessRequired && ($reflectionProperty->isProtectedSet() || $reflectionProperty->isPrivateSet())) {
708+
return false;
709+
}
710+
707711
return (bool) ($reflectionProperty->getModifiers() & $this->propertyReflectionFlags);
708712
} catch (\ReflectionException) {
709713
// Return false if the property doesn't exist

‎src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\PropertyInfo\PropertyReadInfo;
1717
use Symfony\Component\PropertyInfo\PropertyWriteInfo;
1818
use Symfony\Component\PropertyInfo\Tests\Fixtures\AdderRemoverDummy;
19+
use Symfony\Component\PropertyInfo\Tests\Fixtures\AsymmetricVisibility;
1920
use Symfony\Component\PropertyInfo\Tests\Fixtures\ConstructorDummy;
2021
use Symfony\Component\PropertyInfo\Tests\Fixtures\DefaultValue;
2122
use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy;
@@ -689,6 +690,19 @@ public static function provideLegacyExtractConstructorTypes(): array
689690
];
690691
}
691692

693+
/**
694+
* @requires PHP 8.4
695+
*/
696+
public function testAsymmetricVisibility()
697+
{
698+
$this->assertTrue($this->extractor->isReadable(AsymmetricVisibility::class, 'publicPrivate'));
699+
$this->assertTrue($this->extractor->isReadable(AsymmetricVisibility::class, 'publicProtected'));
700+
$this->assertFalse($this->extractor->isReadable(AsymmetricVisibility::class, 'protectedPrivate'));
701+
$this->assertFalse($this->extractor->isWritable(AsymmetricVisibility::class, 'publicPrivate'));
702+
$this->assertFalse($this->extractor->isWritable(AsymmetricVisibility::class, 'publicProtected'));
703+
$this->assertFalse($this->extractor->isWritable(AsymmetricVisibility::class, 'protectedPrivate'));
704+
}
705+
692706
/**
693707
* @dataProvider typesProvider
694708
*/

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.