Merge branch '5.2' into 5.x
* 5.2: [VarDumper] Fix display of nullable union return types. [VarDumper] fixed displaying "mixed" as "?mixed" Handle failure when sending DATA
This commit is contained in:
commit
a952f0fe34
@ -18,6 +18,8 @@ use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport;
|
|||||||
use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream;
|
use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream;
|
||||||
use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream;
|
use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream;
|
||||||
use Symfony\Component\Mime\Address;
|
use Symfony\Component\Mime\Address;
|
||||||
|
use Symfony\Component\Mime\Email;
|
||||||
|
use Symfony\Component\Mime\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Mime\RawMessage;
|
use Symfony\Component\Mime\RawMessage;
|
||||||
|
|
||||||
class SmtpTransportTest extends TestCase
|
class SmtpTransportTest extends TestCase
|
||||||
@ -86,6 +88,29 @@ class SmtpTransportTest extends TestCase
|
|||||||
$transport->send(new RawMessage('Message 3'), $envelope);
|
$transport->send(new RawMessage('Message 3'), $envelope);
|
||||||
$this->assertContains("NOOP\r\n", $stream->getCommands());
|
$this->assertContains("NOOP\r\n", $stream->getCommands());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSendInvalidMessage()
|
||||||
|
{
|
||||||
|
$stream = new DummyStream();
|
||||||
|
|
||||||
|
$transport = new SmtpTransport($stream);
|
||||||
|
$transport->setPingThreshold(1);
|
||||||
|
|
||||||
|
$message = new Email();
|
||||||
|
$message->to('recipient@example.org');
|
||||||
|
$message->from('sender@example.org');
|
||||||
|
$message->attachFromPath('/does_not_exists');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$transport->send($message);
|
||||||
|
$this->fail('Expected Symfony\Component\Mime\Exception\InvalidArgumentException to be thrown');
|
||||||
|
} catch (InvalidArgumentException $e) {
|
||||||
|
$this->assertMatchesRegularExpression('{Path "/does_not_exists"}i', $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertNotContains("\r\n.\r\n", $stream->getCommands());
|
||||||
|
$this->assertTrue($stream->isClosed());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DummyStream extends AbstractStream
|
class DummyStream extends AbstractStream
|
||||||
@ -164,4 +189,10 @@ class DummyStream extends AbstractStream
|
|||||||
{
|
{
|
||||||
return $this->closed;
|
return $this->closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function terminate(): void
|
||||||
|
{
|
||||||
|
parent::terminate();
|
||||||
|
$this->closed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ class SmtpTransport extends AbstractTransport
|
|||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf('smtp://sendmail');
|
return 'smtp://sendmail';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -200,10 +200,19 @@ class SmtpTransport extends AbstractTransport
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->executeCommand("DATA\r\n", [354]);
|
$this->executeCommand("DATA\r\n", [354]);
|
||||||
|
try {
|
||||||
foreach (AbstractStream::replace("\r\n.", "\r\n..", $message->toIterable()) as $chunk) {
|
foreach (AbstractStream::replace("\r\n.", "\r\n..", $message->toIterable()) as $chunk) {
|
||||||
$this->stream->write($chunk, false);
|
$this->stream->write($chunk, false);
|
||||||
}
|
}
|
||||||
$this->stream->flush();
|
$this->stream->flush();
|
||||||
|
} catch (TransportExceptionInterface $e) {
|
||||||
|
throw $e;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->stream->terminate();
|
||||||
|
$this->started = false;
|
||||||
|
$this->getLogger()->debug(sprintf('Email transport "%s" stopped', __CLASS__));
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
$this->executeCommand("\r\n.\r\n", [250]);
|
$this->executeCommand("\r\n.\r\n", [250]);
|
||||||
$message->appendDebug($this->stream->getDebug());
|
$message->appendDebug($this->stream->getDebug());
|
||||||
$this->lastMessageTime = microtime(true);
|
$this->lastMessageTime = microtime(true);
|
||||||
|
@ -195,7 +195,7 @@ class ReflectionCaster
|
|||||||
if (isset($a[$prefix.'returnType'])) {
|
if (isset($a[$prefix.'returnType'])) {
|
||||||
$v = $a[$prefix.'returnType'];
|
$v = $a[$prefix.'returnType'];
|
||||||
$v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
|
$v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
|
||||||
$a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType']->allowsNull() ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
|
$a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType'] instanceof \ReflectionNamedType && $a[$prefix.'returnType']->allowsNull() && 'mixed' !== $v ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
|
||||||
}
|
}
|
||||||
if (isset($a[$prefix.'class'])) {
|
if (isset($a[$prefix.'class'])) {
|
||||||
$a[$prefix.'class'] = new ClassStub($a[$prefix.'class']);
|
$a[$prefix.'class'] = new ClassStub($a[$prefix.'class']);
|
||||||
@ -351,7 +351,7 @@ class ReflectionCaster
|
|||||||
if (!$type instanceof \ReflectionNamedType) {
|
if (!$type instanceof \ReflectionNamedType) {
|
||||||
$signature .= $type.' ';
|
$signature .= $type.' ';
|
||||||
} else {
|
} else {
|
||||||
if (!$param->isOptional() && $param->allowsNull()) {
|
if (!$param->isOptional() && $param->allowsNull() && 'mixed' !== $type->getName()) {
|
||||||
$signature .= '?';
|
$signature .= '?';
|
||||||
}
|
}
|
||||||
$signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' ';
|
$signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' ';
|
||||||
|
@ -165,6 +165,68 @@ EOTXT
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testReflectionParameterMixed()
|
||||||
|
{
|
||||||
|
$f = eval('return function (mixed $a) {};');
|
||||||
|
$var = new \ReflectionParameter($f, 0);
|
||||||
|
|
||||||
|
$this->assertDumpMatchesFormat(
|
||||||
|
<<<'EOTXT'
|
||||||
|
ReflectionParameter {
|
||||||
|
+name: "a"
|
||||||
|
position: 0
|
||||||
|
allowsNull: true
|
||||||
|
typeHint: "mixed"
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, $var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testReflectionParameterUnion()
|
||||||
|
{
|
||||||
|
$f = eval('return function (int|float $a) {};');
|
||||||
|
$var = new \ReflectionParameter($f, 0);
|
||||||
|
|
||||||
|
$this->assertDumpMatchesFormat(
|
||||||
|
<<<'EOTXT'
|
||||||
|
ReflectionParameter {
|
||||||
|
+name: "a"
|
||||||
|
position: 0
|
||||||
|
typeHint: "int|float"
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, $var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testReflectionParameterNullableUnion()
|
||||||
|
{
|
||||||
|
$f = eval('return function (int|float|null $a) {};');
|
||||||
|
$var = new \ReflectionParameter($f, 0);
|
||||||
|
|
||||||
|
$this->assertDumpMatchesFormat(
|
||||||
|
<<<'EOTXT'
|
||||||
|
ReflectionParameter {
|
||||||
|
+name: "a"
|
||||||
|
position: 0
|
||||||
|
allowsNull: true
|
||||||
|
typeHint: "int|float|null"
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, $var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testReturnType()
|
public function testReturnType()
|
||||||
{
|
{
|
||||||
$f = eval('return function ():int {};');
|
$f = eval('return function ():int {};');
|
||||||
@ -184,6 +246,72 @@ EOTXT
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testMixedReturnType()
|
||||||
|
{
|
||||||
|
$f = eval('return function (): mixed {};');
|
||||||
|
$line = __LINE__ - 1;
|
||||||
|
|
||||||
|
$this->assertDumpMatchesFormat(
|
||||||
|
<<<EOTXT
|
||||||
|
Closure(): mixed {
|
||||||
|
returnType: "mixed"
|
||||||
|
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
|
||||||
|
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
||||||
|
file: "%sReflectionCasterTest.php($line) : eval()'d code"
|
||||||
|
line: "1 to 1"
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, $f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testUnionReturnType()
|
||||||
|
{
|
||||||
|
$f = eval('return function (): int|float {};');
|
||||||
|
$line = __LINE__ - 1;
|
||||||
|
|
||||||
|
$this->assertDumpMatchesFormat(
|
||||||
|
<<<EOTXT
|
||||||
|
Closure(): int|float {
|
||||||
|
returnType: "int|float"
|
||||||
|
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
|
||||||
|
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
||||||
|
file: "%sReflectionCasterTest.php($line) : eval()'d code"
|
||||||
|
line: "1 to 1"
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, $f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 8
|
||||||
|
*/
|
||||||
|
public function testNullableUnionReturnType()
|
||||||
|
{
|
||||||
|
$f = eval('return function (): int|float|null {};');
|
||||||
|
$line = __LINE__ - 1;
|
||||||
|
|
||||||
|
$this->assertDumpMatchesFormat(
|
||||||
|
<<<EOTXT
|
||||||
|
Closure(): int|float|null {
|
||||||
|
returnType: "int|float|null"
|
||||||
|
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
|
||||||
|
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
||||||
|
file: "%sReflectionCasterTest.php($line) : eval()'d code"
|
||||||
|
line: "1 to 1"
|
||||||
|
}
|
||||||
|
EOTXT
|
||||||
|
, $f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testGenerator()
|
public function testGenerator()
|
||||||
{
|
{
|
||||||
if (\extension_loaded('xdebug')) {
|
if (\extension_loaded('xdebug')) {
|
||||||
|
Reference in New Issue
Block a user